Difference between staticmethod and classmethod

后端 未结 28 2088
一整个雨季
一整个雨季 2020-11-21 06:11

What is the difference between a function decorated with @staticmethod and one decorated with @classmethod?

28条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2020-11-21 06:57

    One pretty important practical difference occurs when subclassing. If you don't mind, I'll hijack @unutbu's example:

    class A: 
        def foo(self, x): 
            print("executing foo(%s, %s)" % (self, x)) 
     
        @classmethod
        def class_foo(cls, x): 
            print("executing class_foo(%s, %s)" % (cls, x))
     
        @staticmethod 
        def static_foo(x): 
            print("executing static_foo(%s)" % x)
    
    class B(A):
        pass
    

    In class_foo, the method knows which class it is called on:

    A.class_foo(1)
    # => executing class_foo(, 1)
    B.class_foo(1)
    # => executing class_foo(, 1)
    

    In static_foo, there is no way to determine whether it is called on A or B:

    A.static_foo(1)
    # => executing static_foo(1)
    B.static_foo(1)
    # => executing static_foo(1)
    

    Note that this doesn't mean you can't use other methods in a staticmethod, you just have to reference the class directly, which means subclasses' staticmethods will still reference the parent class:

    class A:
        @classmethod
        def class_qux(cls, x):
            print(f"executing class_qux({cls}, {x})")
        
        @classmethod
        def class_bar(cls, x):
            cls.class_qux(x)
    
        @staticmethod
        def static_bar(x):
            A.class_qux(x)
    
    class B(A):
        pass
    
    A.class_bar(1)
    # => executing class_qux(, 1)
    B.class_bar(1)
    # => executing class_qux(, 1)
    A.static_bar(1)
    # => executing class_qux(, 1)
    B.static_bar(1)
    # => executing class_qux(, 1)
    

提交回复
热议问题