gpt4 book ai didi

python - Python 装饰器有必要吗?

转载 作者:行者123 更新时间:2023-11-30 21:53:52 24 4
gpt4 key购买 nike

我对装饰器有基本的了解,但到目前为止它们似乎是多余的并且“hacky”,就像 C 宏但用于函数。

An article为了强调装饰器的重要性,给出了装饰器使用的示例:

from myapp.log import logger

def log_order_event(func):
def wrapper(*args, **kwargs):
logger.info("Ordering: %s", func.__name__)
order = func(*args, **kwargs)
logger.debug("Order result: %s", order.result)
return order
return wrapper

@log_order_event
def order_pizza(*toppings):
# let's get some pizza!

order_pizza(*toppings) # 用法

这不是相当于下面的无装饰器代码吗?

from myapp.log import logger

def log_order_event(func, *args, **kwargs):
logger.info("Ordering: %s", func.__name__)
order = func(*args, **kwargs)
logger.debug("Order result: %s", order.result)
return order

def order_pizza(*toppings):
# let's get some pizza!

log_order_event(order_pizza, *toppings) # 用法

事实上,第二个代码片段不是更容易编写吗,因为它是一个函数,而不是一个函数和一个包装函数?使用调用更长,但它们更清楚地表明实际调用的内容。

这纯粹是品味和语法糖的问题,还是我错过了什么?

最佳答案

就行为而言,两个片段是等效的。但是,我使用装饰器版本有两个主要原因:

  1. 可读性:对于代码片段 2,您需要对一个不太相关的方法进行显式函数调用 log_order_event(),其主要目的是记录。其他方法(例如 order_appetizers())可能需要此日志记录功能,因此,您需要为每个此类方法单独调用 log_order_event()。 (从可读性的角度来看)一次性定义一个执行日志记录的包装器,并且您可以在必要时为此类方法调用包装器(作为装饰器)不是更好吗?装饰器是语法糖,但肯定不是黑客。事实上,PEP 318清楚地讨论了装饰器背后的动机,你一定要读一下。
  2. 可扩展性:考虑这样一种情况,您的代码有多个方法(例如 20 个),例如 order_appetizers()order_maincourse()order_desserts() 等等。我们还假设您想在订购任何这些商品之前执行一些预先检查,例如检查配料(披萨)、卡路里(甜点)等。使用装饰器时,只需在每个检查的单独包装类中定义包装函数,将其导入到主代码中并分别装饰所需的方法即可。这样,您的包装器函数就完全隔离,并且主要逻辑保持干净且易于维护。

    @check_toppings
    @log_order_event
    def order_pizza(*toppings):
    # let's get some pizza!

    @check_calories
    @log_order_event
    def order_desserts():
    # let's order some desserts!
    ...and so on for 20 more methods

    使用无装饰器逻辑,虽然您可以将检查(和日志)方法分离到单独的类中并导入到主逻辑中,但您仍然需要向每个方法添加单独的调用在每个 order 方法中,从代码维护的角度来看,这可能会令人望而生畏,尤其是对于新手来说。

关于python - Python 装饰器有必要吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59493259/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com