2009-12-23 28 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