Python 我应该何时使用@classmethod和何时使用def方法(self)?

Python 我应该何时使用@classmethod和何时使用def方法(self)?,python,language-lawyer,class-method,method-dispatch,language-details,Python,Language Lawyer,Class Method,Method Dispatch,Language Details,在集成我以前从未使用过的Django应用程序时,我发现有两种不同的方法用于在类中定义函数。作者似乎非常有意地使用它们。第一个是我自己经常使用的: class Dummy(object): def some_function(self,*args,**kwargs): do something here self is the class instance 另一个是我不使用的,主要是因为我不知道什么时候使用它,以及它的用途: class Dummy(ob

在集成我以前从未使用过的Django应用程序时,我发现有两种不同的方法用于在类中定义函数。作者似乎非常有意地使用它们。第一个是我自己经常使用的:

class Dummy(object):

    def some_function(self,*args,**kwargs):
        do something here
        self is the class instance
另一个是我不使用的,主要是因为我不知道什么时候使用它,以及它的用途:

class Dummy(object):

    @classmethod
    def some_function(cls,*args,**kwargs):
        do something here
        cls refers to what?
在Python文档中,
classmethod
decorator用以下句子解释:

类方法将类作为隐式的第一个参数接收,只是 与实例类似,方法接收实例

所以我猜
cls
指的是
Dummy
本身(类,而不是实例)。我不太明白为什么会有这种情况,因为我总是可以做到:

type(self).do_something_with_the_class

这仅仅是为了清楚起见,还是我错过了最重要的部分:没有它就无法完成的可怕而迷人的事情?

你的猜测是正确的-你知道
classmethod
的工作原理

为什么可以在实例或类上调用这些方法(在这两种情况下,类对象都将作为第一个参数传递):

关于在实例上使用这些方法的说明:在实例上调用classmethod至少有两种主要用途:

  • self.some_function()
    将调用实际类型的
    self
    some_function
    版本,而不是调用发生在其中的类(如果重命名该类,则无需注意);及
  • 的情况下,一些_函数
    是实现某些协议所必需的,但是单独调用类对象很有用
  • staticmethod
    的区别:还有另一种定义不访问实例数据的方法的方法,称为
    staticmethod
    。它创建了一个根本不接收隐式第一个参数的方法;因此,不会向它传递有关调用它的实例或类的任何信息

    In [6]: class Foo(object): some_static = staticmethod(lambda x: x+1)
    
    In [7]: Foo.some_static(1)
    Out[7]: 2
    
    In [8]: Foo().some_static(1)
    Out[8]: 2
    
    In [9]: class Bar(Foo): some_static = staticmethod(lambda x: x*2)
    
    In [10]: Bar.some_static(1)
    Out[10]: 2
    
    In [11]: Bar().some_static(1)
    Out[11]: 2
    

    我发现它的主要用途是将现有函数(不希望收到
    self
    )调整为类(或对象)上的方法。

    您的猜测是正确的-您了解
    classmethod
    的工作原理

    为什么可以在实例或类上调用这些方法(在这两种情况下,类对象都将作为第一个参数传递):

    关于在实例上使用这些方法的说明:在实例上调用classmethod至少有两种主要用途:

  • self.some_function()
    将调用实际类型的
    self
    some_function
    版本,而不是调用发生在其中的类(如果重命名该类,则无需注意);及
  • 的情况下,一些_函数
    是实现某些协议所必需的,但是单独调用类对象很有用
  • staticmethod
    的区别:还有另一种定义不访问实例数据的方法的方法,称为
    staticmethod
    。它创建了一个根本不接收隐式第一个参数的方法;因此,不会向它传递有关调用它的实例或类的任何信息

    In [6]: class Foo(object): some_static = staticmethod(lambda x: x+1)
    
    In [7]: Foo.some_static(1)
    Out[7]: 2
    
    In [8]: Foo().some_static(1)
    Out[8]: 2
    
    In [9]: class Bar(Foo): some_static = staticmethod(lambda x: x*2)
    
    In [10]: Bar.some_static(1)
    Out[10]: 2
    
    In [11]: Bar().some_static(1)
    Out[11]: 2
    

    <> P>我们发现,它的主要用途是使现有函数(不期望接收<代码>自身/代码>)成为类(或对象)上的方法。

    < P>如果添加DealthCuffCalm方法,那意味着您将使该方法成为java或C++的静态方法。(静态方法是一个通用术语我猜;)) Python还有@staticmethod。classmethod和staticmethod的区别在于是否可以 使用参数或类名本身访问类或静态变量

    class TestMethod(object):
        cls_var = 1
        @classmethod
        def class_method(cls):
            cls.cls_var += 1
            print cls.cls_var
    
        @staticmethod
        def static_method():
            TestMethod.cls_var += 1
            print TestMethod.cls_var
    #call each method from class itself.
    TestMethod.class_method()
    TestMethod.static_method()
    
    #construct instances
    testMethodInst1 = TestMethod()    
    testMethodInst2 = TestMethod()   
    
    #call each method from instances
    testMethodInst1.class_method()
    testMethodInst2.static_method()
    
    所有这些类将cls.cls_var增加1并打印它

    在同一范围内使用相同名称的每个类或用这些类构造的实例将共享这些方法。 只有一个TestMethod.cls\u var 而且只有一个TestMethod.class_method(),TestMethod.static_method()

    这是一个非常重要的问题。为什么需要这些方法

    将类作为工厂创建时,classmethod或staticmethod非常有用
    或者只需初始化一次类。比如打开文件一次,并使用Posil方法逐行读取文件。

    < P>如果添加DealthCuffCalm方法,那就意味着你将把该方法作为java或C++的静态方法。(静态方法是一个通用术语我猜;)) Python还有@staticmethod。classmethod和staticmethod的区别在于是否可以 使用参数或类名本身访问类或静态变量

    class TestMethod(object):
        cls_var = 1
        @classmethod
        def class_method(cls):
            cls.cls_var += 1
            print cls.cls_var
    
        @staticmethod
        def static_method():
            TestMethod.cls_var += 1
            print TestMethod.cls_var
    #call each method from class itself.
    TestMethod.class_method()
    TestMethod.static_method()
    
    #construct instances
    testMethodInst1 = TestMethod()    
    testMethodInst2 = TestMethod()   
    
    #call each method from instances
    testMethodInst1.class_method()
    testMethodInst2.static_method()
    
    所有这些类将cls.cls_var增加1并打印它

    在同一范围内使用相同名称的每个类或用这些类构造的实例将共享这些方法。 只有一个TestMethod.cls\u var 而且只有一个TestMethod.class_method(),TestMethod.static_method()

    这是一个非常重要的问题。为什么需要这些方法

    将类作为工厂创建时,classmethod或staticmethod非常有用
    或者只需初始化一次类。就像只打开一次文件,然后使用feed方法逐行读取文件一样。

    基本上,当您意识到方法的定义不会被更改或覆盖时,应该使用@classmethod


    另外:从理论上讲,类方法比对象方法更快,因为不需要实例化,并且需要更少的内存。

    基本上,当您意识到方法的定义不会更改或重写时,应该使用@classmethod

    另外:从理论上讲,类方法比对象方法更快,因为不需要实例化,并且需要更少的内存。

    (a)Stat