@classmethod和python中的'经典'方法有什么区别,
我@classmethod什么时候应该使用,什么时候应该在python中使用'经典'方法.classmethod必须是一个被引用给类的方法(我的意思是它只是一个处理类的方法)?
我知道@staticmethod和经典方法Thx之间有什么区别
如果在类中定义一个方法,它将以一种特殊的方式处理:对它的访问将其包装在一个特殊的对象中,该对象修改调用参数以包含self对引用对象的引用:
class A(object):
def f(self):
pass
a = A()
a.f()
Run Code Online (Sandbox Code Playgroud)
这个调用a.f实际上要求f(通过描述符 协议)一个对象真正返回.然后在没有参数的情况下调用此对象,并将调用偏转到实数f,并a在前面添加.
那么a.f()真正做的是f用(a)参数调用原始函数.
为了防止这种情况,我们可以包装该函数
@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
Run Code Online (Sandbox Code Playgroud)
所以@classmethod并且@staticmethod有一个共同点,就是他们"不关心"他们被称为的具体对象; 不同之处在于,@staticmethod它不想知道任何关于它的东西,同时@classmethod想要知道它的类.
所以后者获取类对象所使用的对象是一个实例.只需更换self与cls在这种情况下.
现在,何时使用什么?
嗯,这很容易处理:
self,则显然需要实例方法.self,但想了解其类,请使用@classmethod.例如,这可以是工厂方法的情况.datetime.datetime.now()就是这样一个例子:你可以通过它的类或实例来调用它,但它会创建一个具有完全不同数据的新实例.我甚至用它们一次来自动生成给定类的子类.self也cls可以使用@staticmethod.如果他们不需要关心子类化,这也可以用于工厂方法.假设您有一个Car代表Car系统中实体的类。
A 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
Run Code Online (Sandbox Code Playgroud)
函数作用于该类的特定实例;通常调用的第一个参数self是实例本身:
def get_colour(self):
return self.colour
Run Code Online (Sandbox Code Playgroud)
总结一下:
用于classmethod实现适用于整个类(而不适用于特定类实例)的方法:
Car.blue_cars()
Run Code Online (Sandbox Code Playgroud)使用实例方法来实现适用于特定实例的方法:
my_car = Car(colour='red')
my_car.get_colour() # should return 'red'
Run Code Online (Sandbox Code Playgroud)