When should I use @classmethod and when def method(self)?

前端 未结 3 1201
北恋
北恋 2020-12-02 05:41

While integrating a Django app I have not used before, I found two different ways used to define functions in classes. The author seems to use them both very intentionally.

相关标签:
3条回答
  • 2020-12-02 05:59

    Basically, you should use a @classmethod when you realize that the definition of the method will not be changed or overriden.

    An additional : teorically, class methods are faster then object methods, because don't need to be instantiated and need less memory.

    0 讨论(0)
  • 2020-12-02 06:00

    Your guess is correct - you understand how classmethods work.

    The why is that these methods can be called both on an instance OR on the class (in both cases, the class object will be passed as the first argument):

    class Dummy(object):
    
        @classmethod
        def some_function(cls,*args,**kwargs):
            print cls
    
    #both of these will have exactly the same effect
    Dummy.some_function()
    Dummy().some_function()
    

    On the use of these on instances: There are at least two main uses for calling a classmethod on an instance:

    1. self.some_function() will call the version of some_function on the actual type of self, rather than the class in which that call happens to appear (and won't need attention if the class is renamed); and
    2. In cases where some_function is necessary to implement some protocol, but is useful to call on the class object alone.

    The difference with staticmethod: There is another way of defining methods that don't access instance data, called staticmethod. That creates a method which does not receive an implicit first argument at all; accordingly it won't be passed any information about the instance or class on which it was called.

    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
    

    The main use I've found for it is to adapt an existing function (which doesn't expect to receive a self) to be a method on a class (or object).

    0 讨论(0)
  • 2020-12-02 06:02

    If you add decorator @classmethod, That means you are going to make that method as static method of java or C++. ( static method is a general term I guess ;) ) Python also has @staticmethod. and difference between classmethod and staticmethod is whether you can access to class or static variable using argument or classname itself.

    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()
    

    all those classes increase cls.cls_var by 1 and print it.

    And every classes using same name on same scope or instances constructed with these class is going to share those methods. There's only one TestMethod.cls_var and also there's only one TestMethod.class_method() , TestMethod.static_method()

    And important question. why these method would be needed.

    classmethod or staticmethod is useful when you make that class as a factory or when you have to initialize your class only once. like open file once, and using feed method to read the file line by line.

    0 讨论(0)
提交回复
热议问题