Today I'm viewing another's code, and saw this:
class A(B):
# Omitted bulk of irrelevant code in the class
def __init__(self, uid=None):
self.uid = str(uid)
@classmethod
def get(cls, uid):
o = cls(uid)
# Also Omitted lots of code here
what does this cls()
function do here?
If I got some other classes inherit this A
class, call it C
, when calling this get method, would this o
use C
class as the caller of cls()
?
For classmethod
s, the first parameter is the class through which the class method is invoked with instead of the usual self
for instancemethod
s (which all methods in a class implicitly are unless specified otherwise).
Here's an example -- and for the sake of exercise, I added an exception that checks the identity of the cls
parameter.
class Base(object):
@classmethod
def acquire(cls, param):
if cls is Base:
raise Exception("Must be called via subclass :(")
return "this is the result of `acquire`ing a %r with %r" % (cls, param)
class Something(Base):
pass
class AnotherThing(Base):
pass
print Something.acquire("example")
print AnotherThing.acquire("another example")
print Base.acquire("this will crash")
this is the result of `acquire`ing a <class '__main__.Something'> with 'example'
this is the result of `acquire`ing a <class '__main__.AnotherThing'> with 'another example'
Traceback (most recent call last):
File "classmethod.py", line 16, in <module>
print Base.acquire("this will crash")
File "classmethod.py", line 5, in acquire
raise Exception("Must be called via subclass :(")
Exception: Must be called via subclass :(
cls
is the constructor function, it will construct class A and call the __init__(self, uid=None)
function.
If you enherit it (with C), the cls will hold 'C', (and not A), see AKX answer.
It's a class factory.
Essentially it the same as calling:
o = A(uid)
cls
in def get(...):
is A
.