2014-02-19 73 views
0

阅读Python标准库。试图了解classmethod。Python - classmethod()

class C: 
    @classmethod 
    def f(x,y): 
     print('words') 

当我键入:

print(classmethod(C)) 

它返回:

<classmethod object at 0x00FAD930> 

怎么会看什么类方法返回,而不是类方法的生成?

+0

你没有类方法的生成所有不同的对象共享。你有classmethod描述符对象。 –

+0

你试过了:'C.f(1,2)'? – Bakuriu

+0

这是Python 3。 – Phoenix

回答

3

你产生classmethod描述符对象:

print(classmethod(C)) 

返回封装在新classmethod对象的类C。这不是一个生成器,当你用它来装饰一个方法时,这是Python实际存储在你的类中的东西。

请记住,函数或类上面的@decorator_expression行只是语法糖,用于替换该对象的额外函数调用; @classmethod以上def f(...)只是意味着Python将用f = classmethod(f)代替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'>> 

它是当你试图访问C.f属性要调用的描述对象的__get__方法。

函数本身也是描述符;一个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

0

更改为:

class C: 
    @classmethod 
    def f(cls, x, y): 
     return 'words' 

不同于传统的类的方法,其中第一个参数是一个参考self,一个类方法接收class为隐式的第一个参数,就像一个实例方法接收实例。

此外,您需要返回一个值来打印它。

2

如果你想给你打电话对C创建classmethodf,你应该做的:

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 
0

类方法是有用的。

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的值跨正在创造并不仅限于一个实例