返回多个函数的装饰器

时间:2019-06-23 00:30:29

标签: python python-decorators

我想编写一个装饰器,将多个函数放入模块名称空间。考虑以下模块:

# my_module.py


from scipy import signal


@desired_decorator(new_size=(8, 16, 32))
def resample(x, new_size):
    return signal.resample(x, new_size)

我现在希望能够从resample_8导入resample_16resample_32my_module。我可以编写装饰器,并使其返回函数列表,但是如何在模块名称空间中使用这些函数呢?

1 个答案:

答案 0 :(得分:3)

由于您无需使用偷偷摸摸的技巧就可以分配给全局词典,因此这几乎是可能的。 (语法不错)

编辑:K,也许是个 lil 偷偷摸摸的。在没有监督Pythonista的情况下,请勿在家中尝试此操作。 martineau

EDIT2:可以通过使用堆栈自检来获取调用者的全局变量,这样可以避免导入问题,但是在非全局命名空间中调用该函数将无法正常工作,或者会在6个月内消除您的困惑。 user2357112

globals()返回全局变量的字典。为此,用户可以导入这些功能

functools.partial是制作部分函数的好方法。这基本上是一个“半完成”函数调用。创建局部函数会使它记住参数和关键字参数,并调用该局部函数将使用参数和关键字参数调用原始函数。进一步了解here

这是您想要的装饰器,尽管我强烈建议您不要使用它。

from functools import partial

def desired_decorator(**kwargs):
    # make sure there's only one keyword argument
    assert len(kwargs) == 1
    # unpack the single keyword and the values
    keyword, values = (*kwargs.items(),)[0]
    # this is the actual decorator that gets called
    def _make_variants(func):
        for value in values:
            # assign to the globals dictionary
            globals()[
                f"{func.__name__}_{value}"
            ] = partial(func, **{keyword: value})
        # keep the original function available
        return func
    return _make_variants

我的替代方法是使用Chris所说的内容,因为从装饰器创建许多功能不利于维护和清晰性。

这是我建议的代码,但是您可以根据需要使用上面的代码。

from functools import partial

# assign your function things here
resample_8 = partial(resample, new_size=8)
# repeat for other names