首页Python【Python内置函数】s...

【Python内置函数】staticmethod()函数

Python 提供了许多内置函数,这些函数是Python语言的一部分,可以直接在Python程序中使用而无需导入任何模块。

本系列将会陆续整理分享一些的Python内置函数。

文章配套代码获取有以下两种途径:
  • 通过百度网盘获取:
链接:https://pan.baidu.com/s/11x9_wCZ3yiYOe5nVcRk2CQ?pwd=mnsj 提取码:mnsj
  • 前往GitHub获取
https://github.com/returu/Python_built-in_functions





01
简介

Python中,staticmethod是一个内置的装饰器,用于将类中的方法定义为静态方法(Static Method)。
  • 静态方法不需要实例化类,也不需要访问类的属性或方法。
  • 静态方法可以通过类名直接调用,也可以通过类的实例调用,但不会自动传递selfcls参数。
  • 静态方法通常用于实现与类相关但不依赖于类实例的功能,例如工具函数。
  • 静态方法与类方法和实例方法的比较:
  • 实例方法:第一个参数是self,表示类的实例。
  • 类方法:第一个参数是cls,表示类本身,用@classmethod装饰。可以访问类的属性和方法。通常用于实现与类相关的方法,例如工厂方法。
  • 静态方法:不需要selfcls参数,用@staticmethod装饰。不依赖于类或实例的状态,可以通过类名或实例调用。
    不依赖于类或实例的状态。class Example:
        def instance_method(self):
            return"这是一个实例方法"

        @classmethod
        def class_method(cls):
            return"这是一个类方法"

        @staticmethod
        def static_method():
            return"这是一个静态方法"

    # 创建类的实例
    obj = Example()

    print(obj.instance_method())  # 输出: 这是一个实例方法
    print(Example.class_method())  # 输出: 这是一个类方法
    print(Example.static_method())  # 输出: 这是一个静态方法
    print(obj.static_method())  # 输出: 这是一个静态方法(静态方法也可以通过实例调用)

    02
    声明方式

    静态方法有以下两种声明方式:
    • 使用装饰器:
    在定义方法时,使用 @staticmethod 装饰器,这是最常用且符合 Python 习惯的方式。
    class MyClass:
        # 使用装饰器
        @staticmethod
        def my_static_method(x, y):
            return x + y

    # 直接在类上调用静态方法
    result = MyClass.my_static_method(5, 3)
    print(result)  # 输出:8

    # 也可以通过实例调用
    instance = MyClass()
    result = instance.my_static_method(5, 3)
    print(result)  # 输出:8

    • 直接调用:
    也可以通过staticmethod()函数将方法包装为静态方法,适用于需要从类外部引用函数的情况。
    def my_method(x, y):
        return x + y

    class MyClass:
        # 从类外部引用函数
        my_static_method = staticmethod(my_method)

    # 调用静态方法
    result = MyClass.my_static_method(5, 3)
    print(result)  # 输出:8

    03
    增强特性

    Python 3.10 为静态方法引入了一些增强特性:
    • 继承方法属性:

    静态方法会自动继承原始函数的元数据,包括:

    • __module__: 函数所属模块名;
    • __name__: 函数名;
    • __qualname__: 函数的限定名(如 ClassName.method);
    • __doc__: 函数的文档字符串;
    • __annotations__: 函数的类型注解。


    这使得静态方法更能够反映原始函数的特性,便于进行检查。

    class Calculator:
        @staticmethod
        def add(x: int, y: int) -> int:
            """Static method to add two integers."""
            return x + y

    # 查看元数据
    print(Calculator.add.__name__)       # 输出: "add"
    print(Calculator.add.__qualname__)   # 输出: "Calculator.add"
    print(Calculator.add.__doc__)        # 输出: "Static method to add two integers."
    print(Calculator.add.__annotations__) # 输出: {'x': <class 'int'>, 'y': <class 'int'>, 'return': <class 'int'>}


    • 新增__wrapped__属性

    静态方法现在拥有__wrapped__ 属性,直接指向被装饰前的原始函数。这使得可以绕过装饰器逻辑,直接访问原始函数。__wrapped__属性并不是由@staticmethod自动添加的,而是通过functools.wraps添加的。

    import functools

    def my_decorator(func):
        # `functools.wraps`是一个装饰器,用于保留被装饰函数的元数据,同时`__wrapped__`属性也会被自动添加,指向原始函数
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            return func(*args, **kwargs)
        return wrapper

    class Calculator:
        @staticmethod
        @my_decorator
        def add(x: int, y: int) -> int:
            """Static method to add two integers."""
            return x + y

    # 现在可以访问 __wrapped__
    original_function = Calculator.add.__wrapped__
    print(original_function(5, 3))  # 输出:8
    # 查看元数据
    print(original_function.__name__)       # 输出: "add"
    print(original_function.__qualname__)   # 输出: "Calculator.add"
    print(original_function.__doc__)        # 输出: "Static method to add two integers."
    print(original_function.__annotations__) # 输出: {'x': <class 'int'>, 'y': <class 'int'>, 'return': <class 'int'>}


    • 作为普通函数调用

    静态方法现在可以像普通函数一样被调用,这为使用它们提供了更多灵活性。

    class StringUtils:
        @staticmethod
        def reverse(s):
            return s[::-1]

    # 将静态方法赋值给变量并直接调用
    func = StringUtils.reverse
    print(func("hello"))  # 输出: "olleh"

    # 直接作为普通函数传递
    def process_string(s, processor):
        return processor(s)

    print(process_string("world", StringUtils.reverse))  # 输出: "dlrow"

    本篇文章来源于微信公众号: 码农设计师

    RELATED ARTICLES

    欢迎留下您的宝贵建议

    Please enter your comment!
    Please enter your name here

    - Advertisment -

    Most Popular

    Recent Comments