I have the following class and I would like to know what the @classmethod
above of each method of the class is for.
class User(db.Model):
name = db.StringProperty(required = True)
pw_hash = db.StringProperty(required = True)
email = db.StringProperty()
@classmethod
def by_id(cls, uid):
return User.get_by_id(uid, parent = users_key())
@classmethod
def by_name(cls, name):
u = User.all().filter('name =', name).get()
return u
@classmethod
def register(cls, name, pw, email = None):
pw_hash = make_pw_hash(name, pw)
return User(parent = users_key(),
name = name,
pw_hash = pw_hash,
email = email)
@classmethod
def login(cls, name, pw):
u = cls.by_name(name)
if u and valid_pw(name, pw, u.pw_hash):
return u
This class is used to create an entity for the App Engine datastore.
@classmethod
, it will receive the class as the first argument, in case it needs to be used for something. It is usually calledcls
by convention. In this example all methods have itdef by_name(cls, name):
. For this purpose, C++ has overloading as a function, but Python doesn't, so this is where it appliesclassmethod
. In short: When this method is called, it is passed to the class as the first argument instead of the instance of that class (as we normally do with methods). This means that you can use the class and its properties inside that method without having to instantiate the class. Example:A practical example:
To complete @eduardo-munizaga 's answer , what you see in this Entity creation is a kind of implementation of the well-known Singleton pattern . Instead of creating instances, you are directly using the class, with its attributes and methods.
But it's still a class, so subclasses can be derived that overload attributes and methods. Specifically, it
User
derives fromdb.Model
, where it will look for its missing attributes and methods. For example, when the methodregister
returns an instanceUser
:This is known as an instance factory . If you parse it right, your class
User
doesn't have any method__init__
to create this instance, so it would be using the one inherited fromdb.Model
which is where the magic is done.