阅读Python标准库。试图理解类方法。
class C:
@classmethod
def f(x,y):
print('words')
当我输入:
print(classmethod(C))
它返回:
<classmethod object at 0x00FAD930>
如何看到classmethod返回的内容而不是classmethod的生成器?
答案 0 :(得分:3)
您正在生成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
。
答案 1 :(得分:2)
如果您想拨打classmethod
上创建的f
C
,请执行以下操作:
C.f(...)
classmethod
是装饰器函数,它将包装传递给它的任何内容并返回classmethod object
:
>>> classmethod(1)
<classmethod object at 0x02FA6370>
请注意,classmethod
的第一个是类本身,按惯例称为cls
:
class C:
@classmethod
def f(cls, x, y):
print("words")
这给出了:
>>> C.f(1, 2)
words
另外,return
值和print
在函数外部:
class C:
@classmethod
def f(cls, x, y):
return "words"
>>> print(C.f(1, 2))
words
答案 2 :(得分:0)
更改为:
class C:
@classmethod
def f(cls, x, y):
return 'words'
与第一个参数是self
引用的传统类方法不同,类方法接收class
作为隐式第一个参数,就像实例方法接收实例一样。
此外,您需要返回一个值来打印它。
答案 3 :(得分:0)
在所有正在创建的不同对象之间共享值时,classmethod非常有用。
class Classtest:
a =10
@classmethod
def hi(cls, x):
cls.a= cls.a+x
print cls.a
h = Classtest()
h.hi(10)
b = Classtest()
b.hi(30)
c = Classtest()
c.hi(40)
>>> ================================ RESTART ================================
>>>
20
50
90
这里变量a的值在所有正在创建的不同对象之间共享,而不仅限于一个实例