Python内置装饰器@classmethod和@staticmethod详细解析

1.关于装饰器的理解可以见文章:

CSDNhttps://mp.csdn.net/mp_blog/creation/editor/135249941

2.内置装饰器的作用:

        Python内置的装饰器是一些在语言中预先定义的修饰符,它们用于修改函数或方法的行为。这些装饰器可以用于实现各种功能,如类方法、静态方法、属性访问控制等

3.常见的内置装饰器:

(1)@classmethod

@classmethod 是一个 Python 的内置装饰器,用于定义类方法。类方法是属于类而不是实例的方法,可以通过类名或实例调用,与实例的状态无关。@classmethod 装饰的方法的第一个参数通常被命名为 cls,表示类本身。

使用方法:无需实例化,直接通过实例对象.方法名 调用

  • 注意:
  • 类方法内不可以直接调用实例方法,也不可以调用实例变量
  • 类和实例都可以直接调用类方法。
  • 红字部分理解:在Python中,类方法内部不能直接调用实例方法或访问实例变量,因为类方法是与类本身相关联的,而不是与实例相关联的。类方法的第一个参数通常被命名为cls,表示类本身,而不是实例。这就导致在类方法内部无法直接访问实例的成员。
  • 例如,在下面的代码中:
  • class MyClass:
        class_variable = "I am a class variable"

        def __init__(self, instance_variable):
            self.instance_variable = instance_variable

        @classmethod
        def print_class_variable(cls):
            # 无法直接访问实例方法或实例变量
            # self.some_instance_method()  # 错误
            # print(self.instance_variable)  # 错误
            print(cls.class_variable)

        def some_instance_method(self):
            print("I am an instance method")

  • print_class_variable 中,直接调用 self.some_instance_method() 或者 print(self.instance_variable) 都会导致错误,因为类方法无法直接访问实例的方法或变量。

  • 如果你需要在类方法内部执行某些与实例相关的操作,你可以通过传递实例作为参数来实现。例如:

  • class MyClass:
        class_variable = "I am a class variable"

        def __init__(self, instance_variable):
            self.instance_variable = instance_variable

        @classmethod
        def print_class_variable_and_instance_method(cls, instance):
            print(cls.class_variable)
            instance.some_instance_method()

        def some_instance_method(self):
            print("I am an instance method")

    # 创建实例
    obj = MyClass("I am an instance variable")

    # 调用类方法,传递实例作为参数
    MyClass.print_class_variable_and_instance_method(obj)

  • @classmethod例子:

    class MyClass:
        class_variable = "I am a class variable"

        def __init__(self, instance_variable):
            self.instance_variable = instance_variable

        @classmethod
        def print_class_variable(cls):
            print(cls.class_variable)

    # 创建实例
    obj = MyClass("I am an instance variable")

    # 调用类方法,无需创建实例
    MyClass.print_class_variable()  # 输出: I am a class variable
     

    步骤解读:

    class MyClass:    #定义了一个名为 MyClass 的类。
        class_variable = "I am a class variable"   #定义了一个类变量 class_variable,它属于类而不是实例。所有该类的实例都共享这个类变量。

        def __init__(self, instance_variable):
            self.instance_variable = instance_variable   #定义了一个构造函数 __init__,用于创建类的实例。构造函数接受一个参数 instance_variable 并将其赋值给实例变量 self.instance_variable

        @classmethod
        def print_class_variable(cls):
            print(cls.class_variable)   #定义了一个类方法 print_class_variable,使用 @classmethod 装饰器。该方法可以通过类名或实例调用,用于打印类变量 class_variable 的值。类方法的第一个参数通常是 cls,表示类本身。

    # 创建实例
    obj = MyClass("I am an instance variable") #创建了一个 MyClass 类的实例,传递了一个参数 "I am an instance variable" 作为构造函数的参数。

    # 调用类方法,无需创建实例
    MyClass.print_class_variable()  # 输出: I am a class variable  #通过类名调用了类方法 print_class_variable,无需创建实例。该方法打印了类变量 class_variable 的值

    在上述例子中,print_class_variable 是一个类方法,可以通过类名调用,也可以通过实例调用。该方法可以访问类的属性(如 class_variable),但不能直接访问实例的属性,因为它与实例的状态无关。

    应用场景:

    1. 在类级别操作类的属性或状态。
    2. 提供不依赖于实例状态的工厂方法。
    3. 在实例化之前对类进行初始化。

    (2)@staticmethod

    @staticmethod 是一个 Python 的一个内置装饰器,用于定义静态方法。静态方法是类中的方法,与类的实例无关,也无法访问类的实例变量或其他实例方法。静态方法通过类名调用,而不是通过实例调用

    例:

    class MathOperations:
        @staticmethod
        def add(x, y):
            return x + y

        @staticmethod
        def multiply(x, y):
            return x * y

    # 通过类名调用静态方法,无需创建实例
    result_add = MathOperations.add(3, 5)
    result_multiply = MathOperations.multiply(3, 5)

    print("Addition Result:", result_add)         # 输出: 8
    print("Multiplication Result:", result_multiply)  # 输出: 15
     

    在这个例子中,addmultiply 是静态方法。它们没有访问类的实例变量,也没有与类的实例相关联。我们通过类名 MathOperations 直接调用这些静态方法,而不需要创建类的实例。

    如果没有使用 @staticmethod 装饰器,而是普通地定义了两个方法,调用这些方法时需要通过创建类的实例来访问,而不是通过类名直接调用。具体来说,将 @staticmethod 去除后的代码如下

    class MathOperations:
        def add(x, y):
            return x + y

        def multiply(x, y):
            return x * y

    # 创建实例
    obj = MathOperations()

    # 通过实例调用方法
    result_add = obj.add(3, 5)
    result_multiply = obj.multiply(3, 5)

    print("Addition Result:", result_add)
    print("Multiplication Result:", result_multiply)
     

    @staticmethod 要点总结:

    1. 静态方法使用 @staticmethod 装饰器进行定义。
    2. 静态方法不与类的实例相关联,可以通过类名直接调用。
    3. 静态方法不能访问类的实例变量或实例方法,仅能访问类级别的属性和方法。
    4. 静态方法通常用于执行与类相关的操作,而不依赖于类的实例。

    4.两个内置装饰器的用法差别

    1. 参数传递:

    2. @classmethod: 类方法的第一个参数是类本身,通常命名为 cls,用于访问类的属性和方法。
    3. @staticmethod: 静态方法没有默认的类或实例参数,它与类和实例无关。
    4. 访问类属性:

    5. @classmethod: 可以访问和修改类的属性,因为它有一个指向类的第一个参数。
    6. @staticmethod: 无法直接访问类的属性,因为它没有指向类的参数。
    7. 访问实例属性:

    8. @classmethod: 不能直接访问实例的属性,因为它没有指向实例的参数。
    9. @staticmethod: 不能直接访问实例的属性,因为它与实例无关。
    10. 调用方式:

    11. @classmethod: 可以通过类名或实例调用,而且会自动将类传递给第一个参数。
    12. @staticmethod: 可以通过类名或实例调用,但不会自动传递类或实例。
    13. 使用场景:

    14. @classmethod: 适用于与类相关的操作,但不依赖于实例的状态。常用于工厂方法或操作类级别的属性。
    15. @staticmethod: 适用于与类和实例无关的操作。如果方法不需要访问类或实例的状态,可以使用静态方法。

    @classmethod@staticmethod 的用法

    class MyClass:
        class_variable = "I am a class variable"

        def __init__(self, instance_variable):
            self.instance_variable = instance_variable

        @classmethod
        def class_method(cls):
            print("Class method:", cls.class_variable)

        @staticmethod
        def static_method():
            print("Static method", MyClass.class_variable)

    # 使用 @classmethod
    MyClass.class_method()  

    # 使用 @staticmethod
    MyClass.static_method()  

    1. MyClass.class_method(): 调用类方法 class_method,输出 "Class method: I am a class variable"。

    2. MyClass.static_method(): 调用静态方法 static_method,输出 "Static method I am a class variable"。在静态方法内部,可以通过类名 MyClass 直接访问类属性 class_variable

    最后输出:

    Class method: I am a class variable
    Static method: I am a class variable

    5.疑惑解答:怎么区分python里面的方法是一个类方法还是一个静态方法还是一个普通方法?

    普通方法:

  • 普通方法是最常见的方法类型。
  • 它们没有特殊的装饰器,也没有额外的参数。
  • 方法的第一个参数通常被命名为 self,用于表示实例本身。
  • class MyClass:
        def ordinary_method(self):
            print("This is an ordinary method")
  • 类方法:

  • 类方法使用 @classmethod 装饰器进行标识。
  • 类方法的第一个参数通常被命名为 cls,用于表示类本身。
  • 类方法可以通过类名或实例调用。
  • class MyClass:
        class_variable = "I am a class variable"

        @classmethod
        def class_method(cls):
            print("This is a class method")
            print(cls.class_variable)

  • 静态方法:

  • 静态方法使用 @staticmethod 装饰器进行标识。
  • 静态方法没有类或实例参数。
  • 静态方法可以通过类名或实例调用。
  • class MyClass:
        @staticmethod
        def static_method():
            print("This is a static method")
     
  • 作者:YOUTH_____

    物联沃分享整理
    物联沃-IOTWORD物联网 » Python内置装饰器@classmethod和@staticmethod详细解析

    发表回复