From the python documentation, the classmethod is roughly equivalent to
class ClassMethod(object):
"Emulate PyClassMethod_Type() in Objects/funcobject.c"
def __init__(self, f):
self.f = f
def __get__(self, obj, klass=None):
print(klass)
if klass is None:
klass = type(obj)
def newfunc(*args):
return self.f(klass, *args)
return newfunc
My question is: In what cases, the klass is None.
I tested with a Test class
class Test(object):
def __init__(self):
pass
@ClassMethod
def fromstring(cls, s):
res = cls()
res.s = s
return res
t1 = Test.fromstring("a")
t2 = Test()
t3 = t2.fromstring("a")
In those cases, the klass is <class 'main.Test'>.
CodePudding user response:
From the docs:
PEP 252 specifies that
__get__()
is callable with one or two arguments. Python’s own built-in descriptors support this specification; however, it is likely that some third-party tools have descriptors that require both arguments. Python’s own__getattribute__()
implementation always passes in both arguments whether they are required or not.
__get__
is specified to be callable with one argument, as the second argument is redundant when the first argument is non-None
. However, object.__getattribute__
and type.__getattribute__
will never call __get__
with a single argument.
Single-argument __get__
calls would have to originate somewhere else - some code other than object.__getattribute__
or type.__getattribute__
calling __get__
manually.
CodePudding user response:
I believe the question why there is a need for these two lines:
if klass is None:
klass = type(obj)
It is true that when calling either Test.fromstring("a")
or t2.fromstring("a")
, the klass argument is filled in automatically as in always present.
However, the __get()__
method can be also called directly by the user (or some other tool) with only the obj argument. The classmethod will still work:
>>> vars(Test)['fromstring'].__get__(t2)("a").s
None
'a'