python - 将带有参数的 Python 装饰器合并为一个装饰器

标签 python python-decorators

<分区>

我正在使用来自两个不同库的两个不同装饰器。比方说:@decorator1(param1, param2)@decorator2(param3, param4)。我经常在许多功能中使用:

from moduleA import decorator1
from moduleB import decorator2

@decorator2(foo='param3', bar='param4')
@decorator1(name='param1', state='param2')
def myfunc(funcpar1, funcpar2):
    ...

因为它每次都会发生,所以我想创建一个自定义装饰器来处理它们。像这样的东西:

@mycustomdecorator(name='param1', state='param2',
                   foo='param3', bar='param4')
def myfunc(funcpar1, funcpar2):
    ...

我该如何实现?

最佳答案

我认为您不应该这样做——使用装饰器的原始名称可提供更好的可读性。

但是,如果你真的想,你可以这样做:

import functools

from moduleA import decorator1
from moduleB import decorator2

def my_decorator(foo, bar, name, state):
    def inner(func):
        @decorator2(foo=foo, bar=bar)
        @decorator1(name=name, state=state)
        @functools.wraps(func)  # Not required, but generally considered good practice
        def newfunc(*args, **kwargs)
            return func(*args, **kwargs)
        return newfunc
    return inner

@my_decorator(foo='param3', bar='param4', name='param1', state='param2')
def myfunc(funcpar1, funcpar2):
    ...

虽然根据评论,这里有一个替代方法:

def my_decorator(foo, bar, name, state):
    def inner(func):
        # Please note that for the exact same result as in the other one, 
        # the order of decorators has to be reversed compared to normal decorating
        newfunc = decorator1(name=name, state=state)(func)
        newfunc = decorator2(foo=foo, bar=bar)(newfunc)
        # Note that functools.wraps shouldn't be required anymore, as the other decorators should do that themselves
        return newfunc
    return inner

对某些人来说,这可能看起来更简单。但是,使用过 Python 的人习惯于使用 @ 应用装饰器——即使仅出于这个原因,我也更喜欢我的第一个选项。我知道第一次阅读这段代码并理解它的作用要花三倍的时间。

这真的很简单 - 只需编写一个返回另一个装饰器的装饰器,该装饰器将用其他两个装饰器装饰它的内部函数;)

为了养成良好的习惯,使用 functools.wraps 可能也是个好主意。它是标准库,对调试和交互式控制台使用有很大帮助:https://docs.python.org/3.7/library/functools.html

但总的来说,我认为多一行代码比单独使用装饰器更清晰。当您再过 3 个月阅读自己的代码时,您会感谢自己。

关于python - 将带有参数的 Python 装饰器合并为一个装饰器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52517273/

相关文章:

python - 从强标签中提取文本

Python函数装饰器错误

python - 如何在 Python 中配置装饰器

python - 如何在 Django 中编写自己的装饰器?

python - DNA 从字符串列表中找到所有匹配项 (python 2.7)

python - NumPy 有像 Pandas 一样的 select_dtypes 吗?

python - Sklearn随机森林模型太大

python - 无法理解如何在装饰器内的包装函数内获取参数

python - 为什么检查从父类(super class)继承的类返回不同的行?

python - 在python中在哪里存储日志文件名?