2009-12-23 23 views
28

在django.utils.tree.py:classmethod在這段代碼中做了什麼?

def _new_instance(cls, children=None, connector=None, negated=False): 
     obj = Node(children, connector, negated) 
     obj.__class__ = cls 
     return obj 
    _new_instance = classmethod(_new_instance) 

我不知道是什麼classmethod這段代碼樣本。有人可以解釋它做了什麼以及如何使用它?

+1

重複數據刪除:HTTP:/ /stackoverflow.com/questions/38238/what-are-class-methods-in-python-for – 2009-12-23 03:46:32

+3

它總是讓我着迷,即使在7年後問題仍然有效和理智! :) – NoobEditor 2016-07-16 18:09:39

回答

112

classmethod是一個描述符,包裝的功能,並且可以調用生成的對象上的類或(等效地)其一個實例:

>>> class x(object): 
... def c1(*args): print 'c1', args 
... c1 = classmethod(c1) 
... @classmethod 
... def c2(*args): print 'c2', args 
... 
>>> inst = x() 
>>> x.c1() 
c1 (<class '__main__.x'>,) 
>>> x.c2() 
c2 (<class '__main__.x'>,) 
>>> inst.c1() 
c1 (<class '__main__.x'>,) 
>>> inst.c2() 
c2 (<class '__main__.x'>,) 

正如你看到的,無論是直接或修飾語法定義它,無論你把它的類或實例中,classmethod始終接收類作爲其第一個參數。

一類方法的主要用途是定義 「另類構造」:

>>> class y(object): 
... def __init__(self, astring): 
...  self.s = astring 
... @classmethod 
... def fromlist(cls, alist): 
...  x = cls('') 
...  x.s = ','.join(str(s) for s in alist) 
...  return x 
... def __repr__(self): 
...  return 'y(%r)' % self.s 
... 
>>> y1 = y('xx') 
>>> y1 
y('xx') 
>>> y2 = y.fromlist(range(3)) 
>>> y2 
y('0,1,2') 

現在,如果你繼承y,在類方法繼續工作,如:

>>> class k(y): 
... def __repr__(self): 
...  return 'k(%r)' % self.s.upper() 
... 
>>> k1 = k.fromlist(['za','bu']) 
>>> k1 
k('ZA,BU') 
+2

好的插圖@AlexMartelli – 2016-06-14 21:42:05

+0

這不是一個構造函數,它是一個工廠方法。 – t3chb0t 2018-02-12 18:58:56

4

這使得可以調用該方法的類,而不是一個對象:

class MyClass(object): 
    def _new_instance(cls, blah): 
     pass 
    _new_instance = classmethod(_new_instance) 

MyClass._new_instance("blah") 
+1

它也更常用作裝飾器:'@classmethod def _new_instance(cls,blah):' – 2009-12-23 02:49:12