调用装饰的外部函数

时间:2017-08-03 18:03:08

标签: python decorator

我正在寻找一种方法让脚本执行一些我不知道名字并在另一个模块上定义的函数(据说是由另一个用户提供),但是用我定义的那些函数装饰。

例如,外部脚本将是:

    from MyScript import preprocess, process, postprocess 

    @preprocess(foo, bar)
    def external_provider_random_name():
        return "foo"

    @process(foobar)
    def external_provider_random():
        return "bar"

    @postprocess(foo, bar)
    def external_provider():
        return "foobar"

我会在我的应用程序中导入它并执行函数(我不知道他们的名字),能够使用修饰函数返回的内容。

我认为装饰器成为瓶子的原因似乎暴露了类似的行为: 用户可以通过使用$@app.route(my/route)装饰函数来定义新路径。然后在对路由执行http调用时执行此函数,并且应用程序可以使用函数返回的任何内容(json)将其返回给用户。

然而,似乎行为不符合装饰器的实际定义,我无法看到我是如何实现这样的。我在这里遗漏了什么或者是否只有装饰器的解决方案?

2 个答案:

答案 0 :(得分:2)

您只需要从包装器中松开传入函数的副本。您可以将函数引用存储为全局名称,listdict或您选择的任何其他方式。

以下是MyScript.py的示例,它将其函数引用存储在dict中:

funcs = { }

def preprocess(*args):
    def wrapper(fn):
        funcs['preprocess'] = fn
        return fn
    return wrapper

def process(*args):
    def wrapper(fn):
        funcs['process'] = fn
        return fn
    return wrapper

def postprocess(*args):
    def wrapper(fn):
        funcs['process'] = fn
        return fn
    return wrapper

在所有初始化之后,您可以这样调用函数:

MyScript.funcs['preprocess']()

答案 1 :(得分:2)

好像你想要创建某种功能注册表。这是一个简单的示例实现,它使用字典来跟踪已注册的函数。

class Tracker(dict):
    def register(self, identifier):
        def wrapper(function):
            self[identifier] = function
            return function
        return wrapper


tracker = Tracker()

@tracker.register('A')
def function_A():
    print('Blah')

tracker['A']() # Blah

如果要注册已定义的功能,可以使用:

tracker.register('A')(function_A)