How to define a class in Python?

Quite simply, I am learning python and I cannot find a link that will tell me how to write the following:

public class Team { private String name; private String logo; private int members; public Team(){} // getters/setters } 

Further:

 Team team = new Team(); team.setName( "Oscar" ); team.setLogo( "http://...." ); team.setMembers( 10 ); 

This is the Team class with properties: name / logo / members

Edit After several attempts, I got the following:

 class Team: pass 

Further

 team = Team() team.name="Oscar" team.logo="http://..." team.members=10 

Is this a python way? Feels weird (coming from a strongly typed language, of course)

+55
python
Sep 30 '09 at 1:02
source share
2 answers
 class Team: def __init__(self): self.name = None self.logo = None self.members = 0 

In Python, you usually don't write getters and setters unless you really have a nontrivial implementation for them (at this point you are using property descriptors).

+55
Sep 30 '09 at 1:06
source share

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:

  1. 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.

  2. 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.

  3. 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/

  4. 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 name "x" is bound to an integer object with value 3 x += 1 # the name "x" is rebound to a different integer object with value 4 x = [] # the name "x" is bound to an empty list object x.append(1) # the 1 is appended to the same list x already had 

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 # prints "[1]" print k1.lst # also prints "[1]" k1.lst.append(2) print k0.lst # prints "[1, 2]" 

The solution is very simple:

 class K(object): def __init__(self, lst=None): if lst is None: self.lst = [] # bind lst with a new, empty list else: self.lst = lst # bind lst with provided list k0 = K() k1 = K() k0.lst.append(1) print k0.lst # prints "[1]" print k1.lst # print "[]" 

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.

+109
Sep 30 '09 at 1:35
source share



All Articles