@staticmethod与@classmethod在Python中的

发布时间 2023-10-15 00:21:35作者: 小满独家

内容来自 DOC https://q.houxu6.top/?s=@staticmethod与@classmethod在Python中的

使用@staticmethod@classmethod装饰器的方法之间有什么区别?

在Python中,静态方法和类方法都是用于将函数与类相关联的方法。它们之间的主要区别在于它们的调用方式和传递的参数。

  1. 静态方法:
    静态方法是类中的方法,但不需要实例化类就可以调用。它们不依赖于类的实例,因此无法访问实例的属性和方法。静态方法使用@staticmethod装饰器进行定义。

    示例:

    class MyClass:
        @staticmethod
        def my_static_method(arg1, arg2):
            # 在这里编写静态方法的代码
            pass
    
        static_method = my_static_method
    
        # 调用静态方法,无需实例化类
        StaticMethod(arg1, arg2)
    
  2. 类方法:
    类方法是类本身的方法,而不是实例的方法。它们可以访问和修改类的属性。类方法使用@classmethod装饰器进行定义。

    示例:

    class MyClass:
        count = 0
    
        @classmethod
        def my_class_method(cls, arg1, arg2):
            # 在这里编写类方法的代码
            MyClass.count += 1
            return cls.count
    
        class_method = my_class_method
    
        # 调用类方法,无需实例化类
        ClassMethod(arg1, arg2)
    

总结:

  • 静态方法不依赖于类的实例,而类方法依赖于类的实例。
  • 静态方法不能访问类的属性和方法,而类方法可以访问和修改类的属性。

也许一些示例代码会有所帮助:请注意fooclass_foostatic_foo的调用签名之间的区别:

class A(object):
    def foo(self, x):
        print(f"执行foo({self}, {x})")

    @classmethod
    def class_foo(cls, x):
        print(f"执行class_foo({cls}, {x})")

    @staticmethod
    def static_foo(x):
        print(f"执行static_foo({x})")

a = A()

下面是对象实例通常调用方法的方式。对象实例a被隐式地作为第一个参数传递。

a.foo(1)
# 执行foo(<__main__.A object at 0xb7dbef0c>, 1)

使用类方法时,对象实例的类被隐式地作为第一个参数传递,而不是self

a.class_foo(1)
# 执行class_foo(<class '__main__.A'>, 1)

您也可以使用类调用class_foo。实际上,如果您将某些内容定义为类方法,那么可能是因为您打算从类而不是从类实例中调用它。A.foo(1)会引发TypeError,但A.class_foo(1)可以正常工作:

A.class_foo(1)
# 执行class_foo(<class '__main__.A'>, 1)

对于类方法,人们发现的一种用途是创建可继承的替代构造函数。

使用静态方法时,既不是self(对象实例)也不是cls(类)被隐式地作为第一个参数传递。它们的行为类似于普通函数,除了您可以从实例或类调用它们之外。

a.static_foo(1)
# 执行static_foo(1)

A.static_foo('hi')
# 执行static_foo(hi)

静态方法用于将与类具有某种逻辑连接的一些函数分组到类中。

foo只是一个函数,但是当您调用a.foo时,您不仅获得函数,还获得了带有对象实例a绑定为第一个参数的函数的“部分应用”版本。foo期望2个参数,而a.foo只期望1个参数。

a绑定到foo。这就是下面所谓的“绑定”的含义:

print(a.foo)
# <bound method A.foo of <__main__.A object at 0xb7d52f0c>>

使用a.class_foo时,a没有绑定到class_foo,而是类A绑定到class_foo

print(a.class_foo)
# <bound method type.class_foo of <class '__main__.A'>>

在这里,使用静态方法,即使它是一个方法,a.static_foo只是返回一个没有参数绑定的好函数。static_foo期望1个参数,而a.static_foo也期望1个参数。

print(a.static_foo)
# <function static_foo at 0xb7d479cc>

当然,当您使用类A而不是类调用static_foo时,也会发生同样的事情。

print(A.static_foo)
# <function static_foo at 0xb7d479cc>