Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I define a class in Python?

Tags:

python

Quite simple, I'm learning Python, and I can't find a reference that tells me how to write the following:

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

Later:

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

That is a class Team with the properties: name/logo/members

Edit

After a few attempts I got this:

class Team:     pass 

Later

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

Is this the Python way? It feels odd (coming from a strongly typed language of course).

like image 261
OscarRyz Avatar asked Sep 30 '09 01:09

OscarRyz


People also ask

How do you define a class?

In object-oriented programming , a class is a template definition of the method s and variable s in a particular kind of object . Thus, an object is a specific instance of a class; it contains real values instead of variables. The class is one of the defining ideas of object-oriented programming.

What is class in __ init __?

What is __init__ in Python? The Default __init__ Constructor in C++ and Java. Constructors are used to initializing the object's state. The task of constructors is to initialize(assign values) to the data members of the class when an object of the class is created.


2 Answers

class Team:   def __init__(self):     self.name = None     self.logo = None     self.members = 0 

In Python, you typically don't write getters and setters, unless you really have a non-trivial implementation for them (at which point you use property descriptors).

like image 31
Martin v. Löwis Avatar answered Oct 13 '22 22:10

Martin v. Löwis


Here is 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 declared that Team inherits from object. This makes Team a "new-style class"; this has been recommended practice in Python since it was introduced in Python 2.2. (In Python 3.0 and above, classes are always "new-style" even if you leave out the (object) notation; but having that notation does no harm and makes the inheritance explicit.) Here's a Stack Overflow discussion of new-style classes.

  2. It's not required, but I made the initializer take optional arguments so that you can initialize the instance on one line, as I did with team and team3. These arguments are named, so you can either provide values as positional parameters (as with team) or you can use the argument= form as I did with team3. When you explicitly specify the name of the arguments, you can specify arguments in any order.

  3. If you needed to have getter and setter functions, perhaps to check something, in Python you can declare special method functions. This is what Martin v. Löwis meant when he said "property descriptors". In Python, it is generally considered good practice to simply assign to member variables, and simply reference them to fetch them, because you can always add in the property descriptors later should you need them. (And if you never need them, then your code is less cluttered and took you less time to write. Bonus!)

Here's a good link about property descriptors: http://adam.gomaa.us/blog/2008/aug/11/the-python-property-builtin/

Note: Adam Gomaa's blog seems to have disappeared from the web. Here's a link to a saved copy at archive.org:

https://web.archive.org/web/20160407103752/http://adam.gomaa.us/blog/2008/aug/11/the-python-property-builtin/

  1. It doesn't really matter if you specify values as part of the call to Team() or if you poke them into your class instance later. The final class instance you end up with 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__) 

The above will print True. (You can easily overload the == operator for Team instances, and make Python do the right thing when you say team == team2, but this doesn't happen by default.)


I left out one thing in the above answer. If you do the optional argument thing on the __init__() function, you need to be careful if you want to provide a "mutable" as an optional argument.

Integers and strings are "immutable". You can never change them in place; what happens instead is Python creates a new object and replaces the one you had before.

Lists and dictionaries are "mutable". You can keep the same object around forever, adding to it and deleting from 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 key thing you need to know: optional arguments are evaluated only once, when the function is compiled. So if you pass a mutable as an optional argument in the __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 the provided list  k0 = K() k1 = K()  k0.lst.append(1)  print(k0.lst)  # prints "[1]" print(k1.lst)  # prints "[]" 

This business of using a default argument value of None, then testing that the argument passed is None, qualifies as a Python design pattern, or at least an idiom you should master.

like image 185
steveha Avatar answered Oct 13 '22 20:10

steveha