@classmethod在Python中的用途是什么?

问题描述

我目前正在学习Python。在OOP中,@classmethod装饰器的用途是什么?通过@classmethod访问类变量并仅通过常规方法访问它有什么区别?就像我可以这样做一样:

class A():
   _variable = A

   def getvariable(self):
      return self._variable 
 

class A():
   _variable = A

   @classmethod
   def getvariable(cls):
      return cls._variable 
 

两种方法有什么区别?为什么在什么时候使用classmethod以及什么时候不需要使用classmethod?如果我不这样做会怎样?

解决方法

使用类和实例变量/方法时,您关心的是可见性!

该类的所有实例共享一个类变量/方法,而该实例变量/方法仅可用于您当前拥有的实例

通常来说,实例变量用于每个实例唯一的数据,而类变量用于该类的所有实例共享的属性和方法:python tutorial

class Dog:

    kind = 'canine'         # class variable shared by all instances

    def __init__(self,name):
        self.name = name    # instance variable unique to each instance

>>> d = Dog('Fido')
>>> e = Dog('Buddy')
>>> d.kind                  # shared by all dogs
'canine'
>>> e.kind                  # shared by all dogs
'canine'
>>> d.name                  # unique to d
'Fido'
>>> e.name                  # unique to e
'Buddy'

此示例未向您显示的是,使用类方法,您可以在不经过实例的情况下在类上调用该方法!

class Dog:

    kind = 'canine'         # class variable shared by all instances

    def __init__(self,name):
        self.name = name    # instance variable unique to each instance

    @classmethod
    def isGoodBoy(cls):
        return True  # all dogs are good boys!

现在isGoodBoy方法不需要访问狗的名字,因此它可以是一个类方法,并且可以反映所有实例;毕竟所有的狗都是好男孩(还有女孩!)。

但这可以告诉您更多!狗是好男孩吗?我们是否要求任何特定的狗成为好男孩?

>> Dog.isGoodBoy() # here we call the method on the class
True # debate settled!

现在再问其他四个问题;在处理类而不是对象时,最好使用类方法。您如何知道记录器实例在创建之前是否需要网络?这就是类方法和类变量的用途,并且该类的所有对象都具有相同的状态和行为。

现在,由于这在所有类之间共享,因此您现在还遇到其他问题,该类的每个实例都可能会修改类变量!这也意味着您可以在没有对象的情况下查询变量值!

假设您要在运行时从方法A切换到方法B。


class Foo:
    upgrade = False
    def a(self):
        ...
    def b(self):
        ...
    def run(self):
        self.a() if self.upgrade else self.b()

现在Foo.upgrade = True将为所有人切换内容!甚至最好通过运行Dog.kind = 'feline'

使狗成为猫科动物 ,

@classmethod定义以下方法是静态的,并且属于类而不是对象。

因此具有@classmethod的方法无法访问对象的任何值,但是可以在不初始化该类对象的情况下调用它。

用例为:

class Test:
    @classmethod
    def foo(cls,a,b):
        # do smth

Test.foo(1,"abc")