亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Industrial programming >> Python

精通 Python 装饰器:专家技巧增强函数

Python 装饰器

装饰器让你用可复用逻辑包装函数,使代码更模块化、可读、可维护。本指南构建、解释并应用装饰器于真实场景。

视频:Python @Decorators

Python 中的装饰器

Python 装饰器是强大的元编程工具,允许在定义时为函数或类添加行为。因 Python 中一切皆对象——包括函数和类——装饰器通过接收一个可调用对象,用另一个包装它,并返回新可调用对象来工作。


学习装饰器的前置知识

深入前,应熟悉 Python 中函数是一等对象。名称只是绑定到对象的引用;同一函数可被多个名称引用。

def first(msg):
    print(msg)
first("Hello")
second = first
second("Hello")

输出

Hello Hello

函数可作为参数传递、从其他函数返回、甚至嵌套在其他函数内。这些概念——高阶函数、嵌套函数、闭包——是装饰器的基石。

def inc(x):
    return x + 1
def dec(x):
    return x - 1
def operate(func, x):
    result = func(x)
    return result

用法:

>>> operate(inc,3)
4
>>> operate(dec,3)
2
def is_called():
    def is_returned():
        print("Hello")
    return is_returned
new = is_called()
new()

输出

Hello

理解闭包是关键:嵌套函数保留对外层作用域的访问,这正是装饰器利用的机制来存储元数据或修改行为。


回到装饰器

在 Python 中,装饰器就是接受函数(或其他可调用对象)并返回新可调用对象的可调用对象。返回函数通常包装原函数,在调用前后添加或改变功能。

def make_pretty(func):
    def inner():
        print("I got decorated")
        func()
    return inner
def ordinary():
    print("I am ordinary")

示例用法:

>>> ordinary()
I am ordinary
>>> pretty = make_pretty(ordinary)
>>> pretty()
I got decorated
I am ordinary

装饰器模式保持原函数语义不变同时增强它。为避免手动重新赋值,Python 提供 @ 语法糖:

@make_pretty
def ordinary():
    print("I am ordinary")

这等价于:

def ordinary():
    print("I am ordinary")
ordinary = make_pretty(ordinary)

装饰带参数的函数

许多装饰器需处理任意参数。*args 和 **kwargs 语法捕获任意位置或关键字参数并原样转发。

def works_for_all(func):
    def inner(*args, **kwargs):
        print("I can decorate any function")
        return func(*args, **kwargs)
    return inner

处理边界情况是装饰器常见用例。例如防除零:

def smart_divide(func):
    def inner(a, b):
        print("I am going to divide", a, "and", b)
        if b == 0:
            print("Whoops! cannot divide")
            return
        return func(a, b)
    return inner
@smart_divide
def divide(a, b):
    print(a/b)

用法:

>>> divide(2,5)
I am going to divide 2 and 5
0.4
>>> divide(2,0)
I am going to divide 2 and 0
Whoops! cannot divide

Python 中链式装饰器

装饰器可堆叠。应用顺序很重要,因每个装饰器接收下方装饰器返回的函数。

def star(func):
    def inner(*args, **kwargs):
        print("*" * 30)
        func(*args, **kwargs)
        print("*" * 30)
    return inner
def percent(func):
    def inner(*args, **kwargs):
        print("%" * 30)
        func(*args, **kwargs)
        print("%" * 30)
    return inner
@star
@percent
def printer(msg):
    print(msg)

结果:

****************************** %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Hello %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ******************************

反转顺序会交换包围模式,演示装饰器堆叠如何影响行为。

Python

  1. 精通Python数据类型:实战指南
  2. 精通Python运算符:全面指南
  3. 精通Python Pass语句:实战指南
  4. 精通Python函数参数:位置、关键字与默认参数
  5. Python Lambda匿名函数实战指南
  6. 精通 Python Lambda 函数:实用示例与最佳实践
  7. Python abs() 函数:计算数字与复数的绝对值
  8. Python round() 函数详解与实战示例
  9. 精通 Python range() 函数:从基础到高级用法
  10. 精通 Python map() 函数:语法、示例与最佳实践
  11. 精通 Python yield:生成器 vs return 实战指南
  12. 精通 Python enumerate():为列表、元组、字符串、字典带索引循环