当前位置:   article > 正文

python-内置装饰器@classmethod 和 @staticmethod 详解

@classmethod

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

CSDNicon-default.png?t=N7T8https://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. 参数传递:

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

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

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

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

    • @classmethod: 适用于与类相关的操作,但不依赖于实例的状态。常用于工厂方法或操作类级别的属性。
    • @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")
     

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小舞很执着/article/detail/903484
推荐阅读
相关标签
  

闽ICP备14008679号