用@staticmethod修饰的方法和用@classmethod修饰的方法有什么区别?


当前回答

我认为一个更好的问题是“你什么时候会使用@classmethod vs@staticmethod?”

@classmethod允许您轻松访问与类定义关联的私有成员。这是一种很好的方法来实现单实例,或者控制所创建对象实例数量的工厂类。

@staticmethod提供了边际性能增益,但我还没有看到静态方法在类内的有效使用,而静态方法不能作为类外的独立函数实现。

其他回答

我将用一个例子来解释基本的区别。

class A(object):
    x = 0

    def say_hi(self):
        pass

    @staticmethod
    def say_hi_static():
        pass

    @classmethod
    def say_hi_class(cls):
        pass

    def run_self(self):
        self.x += 1
        print self.x # outputs 1
        self.say_hi()
        self.say_hi_static()
        self.say_hi_class()

    @staticmethod
    def run_static():
        print A.x  # outputs 0
        # A.say_hi() #  wrong
        A.say_hi_static()
        A.say_hi_class()

    @classmethod
    def run_class(cls):
        print cls.x # outputs 0
        # cls.say_hi() #  wrong
        cls.say_hi_static()
        cls.say_hi_class()

1-我们可以直接调用静态和类方法,而无需初始化

# A.run_self() #  wrong
A.run_static()
A.run_class()

2-静态方法不能调用self方法,但可以调用其他静态和类方法

3-静态方法属于类,根本不会使用对象。

4-类方法不绑定到对象,而是绑定到类。

对iPython中其他相同方法的快速破解表明,@staticmethod产生了边际性能增益(以纳秒为单位),但在其他方面它似乎没有任何作用。此外,在编译过程中通过staticmethod()处理方法的额外工作(这在运行脚本时任何代码执行之前发生)可能会抵消任何性能提升。

为了代码的可读性,我会避免@staticmethod,除非您的方法将用于纳秒计数的工作量。

关于如何在Python中使用静态、类或抽象方法的权威指南是本主题的一个很好的链接,总结如下。

@staticmethod函数只不过是在类中定义的函数。它可以在不首先实例化类的情况下调用。它的定义通过继承是不可变的。

Python不必为对象实例化绑定方法。它简化了代码的可读性,并且不依赖于对象本身的状态;

@classmethod函数也可以在不实例化类的情况下调用,但它的定义遵循子类,而不是父类,通过继承,可以被子类重写。这是因为@classmethod函数的第一个参数必须始终是cls(class)。

工厂方法,用于使用例如某种预处理为类创建实例。静态方法调用静态方法:如果将静态方法拆分为多个静态方法,则不应硬编码类名,而应使用类方法

分析@staticmethod,提供不同的见解。

类的普通方法是一种隐式动态方法,它将实例作为第一个参数。相反,静态方法不将实例作为第一个参数,因此称为“static”。

静态方法确实是一个与类定义之外的函数相同的正常函数。幸运的是,它被分组到类中,只是为了更接近应用它的位置,或者您可以滚动查找它。

太长,读不下去了

静态方法本质上是绑定到类(及其实例)的函数

类方法本质上是一种可继承的静态方法。

有关详细信息,请参阅其他人的优秀答案。