Вы производите объект classmethod
дескриптора:
print(classmethod(C))
возвращает класс C
обернутый в новом classmethod
объекта. Это не генератор, это то, что Python фактически хранит в вашем классе, когда вы украшаете его с помощью этого метода.
Помните, что строка @decorator_expression
над функцией или классом является просто синтаксическим сахаром для вызова дополнительной функции, заменяющей этот объект; @classmethod
выше def f(...)
означает, что Python заменит f
на f = classmethod(f)
.
Вы можете видеть объект того же типа, если смотреть на значение C.__dict__['f']
; это тот же тип объекта:
>>> class C:
... @classmethod
... def f(x,y):
... print('words')
...
>>> C.__dict__['f']
<classmethod object at 0x107d00810>
>>> C.__dict__['f'].__get__(None, C)
<bound method type.f of <class '__main__.C'>>
>>> C.f
<bound method type.f of <class '__main__.C'>>
Это __get__
метод на объект дескриптора, который вызывается, когда вы пытаетесь получить доступ к атрибуту C.f
.
Функции сами по себе являются дескрипторами; a classmethod
обходит метод функции .__get__
, чтобы обеспечить привязку к классу вместо обычного привязки к экземпляру.
См. descriptor HOWTO, чтобы понять, что такое дескриптор, и как работает объект classmethod
.
Чтобы видеть то, что сам метод возвращает, просто вызовите его на классе или на экземпляре:
>>> class C:
... @classmethod
... def f(*args, **kw):
... return args, kw
... def regular(*args, **kw):
... return args, kw
...
>>> C.f()
((<class '__main__.C'>,), {})
>>> C().f()
((<class '__main__.C'>,), {})
>>> C.regular()
((), {})
>>> C().regular()
((<__main__.C object at 0x1085b0790>,), {})
Вместо обычного объекта self
например, метод вместо передается ссылка на класс. Для вызова C.f()
(непосредственно в классе) и C().f()
(на примере C
) первым аргументом f()
является C
.
Сравните это с методом C.regular()
; это обычный метод и при вызове непосредственно с классом с C.regular()
аргументы не были переданы, когда вызывается экземпляр с C().regular()
первым аргументом, экземпляр был передан. Это то, что вы обычно используете в методе self
подпись.
Для методов класса первый аргумент обычно называется cls
при объявлении вашего метода.
Вы не имеете генератор Метод класса. У вас есть объект дескриптора класса. –
Вы пытались: 'C.f (1,2)'? – Bakuriu
Это Python 3. – Phoenix