@classmethod和python中的方法之间的区别
这个问题在这里已经有了答案:
假设您有一个Car
类,它代表您的系统中的Car
实体。
一classmethod
是,对于类的工作方式方法Car
不上任何一个Car
的情况。 因此,用@classmethod
装饰的函数的第一个参数(通常称为cls
)是类本身。 例:
class Car(object):
colour = 'red'
@classmethod
def blue_cars(cls):
# cls is the Car class
# return all blue cars by looping over cls instances
函数作用于该类的特定实例; 通常称为self
的第一个参数就是实例本身:
def get_colour(self):
return self.colour
总结一下:
使用classmethod
实现在整个类(而不是特定的类实例)上工作的方法:
Car.blue_cars()
使用实例方法来实现在特定实例上工作的方法:
my_car = Car(colour='red')
my_car.get_colour() # should return 'red'
如果你在一个类中定义了一个方法,它将以一种特殊的方式处理:对它的访问将其包含在一个修改调用参数的特殊对象中,以包含self
,对被引用对象的引用:
class A(object):
def f(self):
pass
a = A()
a.f()
这个对af
调用实际上要求f
(通过描述符协议)让对象真正返回。 然后,该对象被称为不带参数和偏转调用真正f
,加入a
在前面。
所以af()
真正做的是用(a)
作为参数调用原始的f
函数。
为了防止这种情况,我们可以包装这个功能
@staticmethod
装饰器, @classmethod
装饰器, @staticmethod
将它变成一个对象,当被问及时,它改变参数传递行为,以便它匹配关于调用原始f
的意图:
class A(object):
def method(self):
pass
@staticmethod
def stmethod():
pass
@classmethod
def clmethod(cls):
pass
a = A()
a.method() # the "function inside" gets told about a
A.method() # doesn't work because there is no reference to the needed object
a.clmethod() # the "function inside" gets told about a's class, A
A.clmethod() # works as well, because we only need the classgets told about a's class, A
a.stmethod() # the "function inside" gets told nothing about anything
A.stmethod() # works as well
所以@classmethod
和@staticmethod
的共同之处在于他们“不关心”他们被调用的具体对象; 不同之处在于@staticmethod
根本不想知道任何事情,而@classmethod
想知道它的类。
所以后者得到的类对象是被使用的对象是一个实例。 在这种情况下,只需将self
cls
。
现在,什么时候用什么?
那么,这很容易处理:
self
,您显然需要实例方法。 self
,但想知道它的类,请使用@classmethod
。 例如,工厂方法就是这种情况。 datetime.datetime.now()
就是这样一个例子:你可以通过它的类或者实例来调用它,但是它会创建一个具有完全不同数据的新实例。 我甚至用它们自动生成给定类的子类。 self
也不需要cls
,你可以使用@staticmethod
。 如果他们不需要关心子类,那么这也可以用于工厂方法。 @classmethod
将类作为第一个参数,而函数则用该类的实例
>>> class Test(object):
... def func(self):
... print self
... @classmethod
... def meth(self):
... print self
>>> t = Test()
>>> t.func()
<__main__.Test object at 0x00000000027238D0>
>>> t.meth()
<class '__main__.Test'>
我用self
的说法meth
有意所以这将是非常接近在语法上的func
。 但通常你最好用cls
作为参数:
... @classmethod
... def meth(cls):
... print cls
链接地址: http://www.djcxy.com/p/9207.html
上一篇: Difference between @classmethod and a method in python
下一篇: @StaticMethod or @ClassMethod decoration on magic methods