2014-02-19 77 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的值跨正在創造並不僅限於一個實例