What does cls() function do inside a class method?
Asked Answered
V

4

32

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()?

Visual answered 17/7, 2014 at 9:13 Comment(1)
cls is A in this case.Denti
B
19

For classmethods, the first parameter is the class through which the class method is invoked with instead of the usual self for instancemethods (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 :(
Beaudette answered 17/7, 2014 at 9:19 Comment(1)
This doesn't really answer the OP's question as to what cls() does in the classmethod he has seen. As I've stated (@classmethods aside) it's a factory.Underling
J
35

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.

Jenevajeni answered 17/7, 2014 at 10:0 Comment(0)
B
19

For classmethods, the first parameter is the class through which the class method is invoked with instead of the usual self for instancemethods (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 :(
Beaudette answered 17/7, 2014 at 9:19 Comment(1)
This doesn't really answer the OP's question as to what cls() does in the classmethod he has seen. As I've stated (@classmethods aside) it's a factory.Underling
U
18

It's a class factory.

Essentially it the same as calling:

o = A(uid)

cls in def get(...): is A.

Underling answered 17/7, 2014 at 9:17 Comment(2)
Feel free to suggest an improved edit. This is a community forum afterall.Underling
There is a large amount of expected knowledge in this answer.Cryptomeria
C
0

It is another way of creating an instance from within the class (as every factory method does), instead of creating an object directly. Why do we need to use this? because this behavior is inheritable, meaning whenever the base class is subclassed, the factory method, whenever invoked, will create an instance for the subclass.

Chordate answered 1/7 at 10:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.