Here's what I would recommend:
class Team(object): def __init__(self, name=None, logo=None, members=0): self.name = name self.logo = logo self.members = members team = Team("Oscar", "http://...", 10) team2 = Team() team2.name = "Fred" team3 = Team(name="Joe", members=10)
Some notes on this:
I stated that Team inherits from object . This makes the team a "new style class"; It has been recommended in Python since its introduction in Python 2.2. (In Python 3.0 and above, classes are always โnew styleโ, even if you skip the notation (object) ; but this notation does no harm and makes inheritance explicit.) Here is a discussion of the Stack Overflow discussion of new style classes.
This is not necessary, but I forced the initializer to accept optional arguments so that you could initialize the instance in one line, as I did with team and team3 . These arguments have names, so you can provide values โโas positional parameters (as with team ) or use the argument= form, as I did with team3 . When you explicitly specify the name of the arguments, you can specify the arguments in any order.
If you need to have get and set functions, maybe something to check, in Python you can declare special method functions. This is what Martin vs. Lewis had in mind when he said "property descriptors." In Python, it is considered good practice to simply assign member variables and simply reference them to retrieve them, because you can always add property descriptors later if you need them. (And if you never need them, then your code will be less cluttered and you will need less time to write. Bonus!)
Here is a good link about property descriptors: http://adam.gomaa.us/blog/2008/aug/11/the-python-property-builtin/
It doesn't really matter if you specified the values โโas part of the Team() call or whether you inserted them into your class instance later. The last instance of the class that you come across will be identical.
team = Team("Joe", "http://example.com", 1) team2 = Team() team2.name = "Joe" team2.logo = "http://example.com" team2.members = 1 print team.__dict__ == team2.__dict__
Above will print True . (You can easily overload the == operator for Team instances and get Python to do the right thing when you say team == team2 , but this does not happen by default.)
UPDATE: I missed one thing in the answer above, and I would like to add this now. If you are executing an optional argument in the __init__() function, you need to be careful if you want to provide "mutable" as an optional argument.
Integers and strings are "immutable". You can never change them in place; Instead, Python creates a new object and replaces the one you had before.
Lists and dictionaries are "volatile". You can store the same object forever by adding and removing it.
x = 3
The main thing you need to know: optional arguments are evaluated only once when the function is compiled. So if you pass mutable as an optional argument to __init__() for your class, then each instance of your class shares one mutable object. This is almost never what you want.
class K(object): def __init__(self, lst=[]): self.lst = lst k0 = K() k1 = K() k0.lst.append(1) print k0.lst
The solution is very simple:
class K(object): def __init__(self, lst=None): if lst is None: self.lst = []
It is the business of using the default argument value of None , and then verifying that the argument passed to is None qualifies as a Python design pattern, or at least an idiom that you have to master.