乐趣区

关于python:Python全景系列9-Python-装饰器优雅地增强你的函数和类

欢送来到咱们的系列博客《Python 全景系列》第九篇!在这个系列中,咱们将率领你从 Python 的基础知识开始,一步步深刻到高级话题,帮忙你把握这门弱小而灵便的编程语法。无论你是编程老手,还是有肯定根底的开发者,这个系列都将提供你须要的常识和技能。

装璜器在 Python 中表演了重要的角色,这是一种精美的语言个性,让咱们可能批改或加强函数和类的行为,无需批改它们的源代码。这篇文章将深入探讨装璜器的所有相干主题,包含装璜器的基础知识、实现与应用、工作原理,以及通过理论例子学习装璜器的独特用法。

Python 装璜器深入探讨

在 Python 中,装璜器提供了一种简洁的形式,用来批改或加强函数和类的行为。装璜器在语法上体现为一个前置于函数或类定义之前的非凡标记:

@simple_decorator
def hello_world():
    print("Hello, world!")

在这个例子中,simple_decorator 是一个装璜器,它作用于下方的 hello_world 函数。装璜器在概念上就像一个包装器,它能够在被装璜的函数执行前后插入任意的代码,进而扭转被装璜函数的行为。

参数化装璜器

咱们还能够进一步将装璜器参数化,这让装璜器的行为更具灵活性。比方,咱们能够定义一个装璜器,让它在函数执行前后打印自定义的音讯:

def message_decorator(before_message, after_message):
    def decorator(func):
        def wrapper(*args, **kwargs):
            print(before_message)
            result = func(*args, **kwargs)
            print(after_message)
            return result
        return wrapper
    return decorator

@message_decorator("Start", "End")
def hello_world():
    print("Hello, world!")

在这个例子中,message_decorator 是一个参数化装璜器,它承受两个参数,别离代表函数执行前后要打印的音讯。

了解装璜器的工作原理

在 Python 中,函数是第一类对象。这意味着函数和其余对象一样,能够作为变量进行赋值,能够作为参数传给其余函数,能够作为其余函数的返回值,甚至能够在一个函数外面定义另一个函数。这个个性是实现装璜器的根底。

def decorator(func):
    def wrapper():
        print('Before function execution')
        func()
        print('After function execution')
    return wrapper

def hello_world():
    print('Hello, world!')

decorated_hello = decorator(hello_world)
decorated_hello()

在这个例子中,decorator 函数接管一个函数 hello_world 作为参数,并返回了一个新的函数 wrapped_func。这个新函数在 hello_world 函数执行前后别离打印一条音讯。咱们能够看到,装璜器实际上是一个返回函数的函数。

函数签名放弃

默认状况下,装璜器会“覆盖”掉原函数的名字和文档字符串。这是因为在装璜器外部,咱们返回了一个全新的函数。咱们能够应用 functools.wraps 来解决这个问题:

import functools

def decorator(func):
    @functools.wraps(func)
    def wrapper():
        print('Before function execution')
        func()
        print('After function execution')
    return wrapper

@decorator
def hello_world():
    "Prints'Hello, world!'"print('Hello, world!')

print(hello_world.__name__)
print(hello_world.__doc__)

这样,应用装璜器后的函数名和文档字符串可能放弃不变。

Python 装璜器的利用实例

装璜器在理论的 Python 编程中有许多利用场景,比方日志记录、性能测试、事务处理、缓存、权限校验等。

一个常见的利用就是应用装璜器进行日志记录:

import logging

def log_decorator(func):
    logging.basicConfig(level=logging.INFO)
    
    def wrapper(*args, **kwargs):
        logging.info(f'Running"{func.__name__}"with arguments {args} and kwargs {kwargs}')
        result = func(*args, **kwargs)
        logging.info(f'Finished"{func.__name__}"with result {result}')
        return result
    
    return wrapper

@log_decorator
def add(x, y):
    return x + y

这个装璜器记录了函数的名称,函数调用的参数,以及函数返回的后果。

装璜器链

Python 容许咱们将多个装璜器利用到一个函数上,造成一个装璜器链。例如,咱们能够同时利用日志装璜器和性能测试装璜器:

import time
import logging
from functools import wraps

def log_decorator(func):
    logging.basicConfig(level=logging.INFO)
    
    @wraps(func)
    def wrapper(*args, **kwargs):
        logging.info(f'Running"{func.__name__}"with arguments {args} and kwargs {kwargs}')
        result = func(*args, **kwargs)
        logging.info(f'Finished"{func.__name__}"with result {result}')
        return result

    return wrapper

def timer_decorator(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print(f'Function"{func.__name__}"took {end_time - start_time} seconds to run.')
        return result

    return wrapper

@log_decorator
@timer_decorator
def add(x, y):
    time.sleep(2)
    return x + y

在这个例子中,@log_decorator@timer_decorator 两个装璜器被同时利用到 add 函数上,它们别离负责记录日志和测量函数运行工夫。

One More Thing: 主动注册装璜器

一个乏味的装璜器利用是主动注册。这个装璜器会在装璜函数时主动将函数增加到一个列表或字典中,这样咱们就能够在程序的其余中央拜访到这个列表或字典,晓得有哪些函数被装璜过。

# 装璜器将函数注册到一个列表中
def register_decorator(func_list):
    def decorator(func):
        func_list.append(func)
        return func
    return decorator

# 主动注册函数
registered_functions = []
@register_decorator(registered_functions)
def foo():
    pass

@register_decorator(registered_functions)
def bar():
    pass

print(registered_functions)  # 输入: [<function foo at 0x10d38d160>, <function bar at 0x10d38d1f0>]

这个装璜器能够用于主动注册路由、插件零碎、命令行参数解决等场景,可能大大提高代码的灵活性和可扩展性。

总结

Python 装璜器是一种弱小的工具,它能够让咱们更无效地治理和组织代码。心愿通过这篇文章,你可能更深刻地了解装璜器的工作原理和用法,从而在你的我的项目中更好地应用装璜器。

如有帮忙,请多关注
集体微信公众号:【Python 全视角】
TeahLead_KrisChang,10+ 年的互联网和人工智能从业教训,10 年 + 技术和业务团队治理教训,同济软件工程本科,复旦工程治理硕士,阿里云认证云服务资深架构师,上亿营收 AI 产品业务负责人。

退出移动版