@classmethod和python中的方法之间的区别

这个问题在这里已经有了答案:

  • Python类方法的一个示例用例是什么? 6个答案

  • 假设您有一个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