简体   繁体   English

调用装饰的外部函数

[英]Calling decorated external functions

I am looking for a way for a script to execute some functions for which I don't know the names and defined on another module (supposedly provided by another user), but decorated with ones that I define. 我正在寻找一种脚本执行某种功能的方法,这些功能我不知道其名称,而是在另一个模块(据说是由另一个用户提供)上定义的,但是以我定义的功能修饰。

For example, the external script would be: 例如,外部脚本为:

    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"

I would in turn import this in my application and execute the functions ( I don't know their name), with the ability to use what the decorated function returns. 然后我将其导入我的应用程序中并执行功能(我不知道它们的名称),并能够使用修饰后的功能返回的内容。

The reason I thought of decorators is become flask seems to expose the similar behavior: the user can define new route by decorating a function with $@app.route(my/route) . 我想到装饰器成为烧瓶的原因似乎暴露了类似的行为:用户可以通过使用$@app.route(my/route)装饰函数来定义新的路由。 This function is then executed when a http call is performed on the route, and the application can use whatever the function returns (a json) to return it to the user. 然后,在路由上执行http调用时,将执行此函数,并且应用程序可以使用该函数返回的任何内容(一个json)将其返回给用户。

However it seems that behavior doesn't fit with the actual definition of decorators, and I can't see how I can achieve such. 但是,这种行为似乎与装饰器的实际定义不符,而且我看不到如何实现。 Am I missing something here or is there a solution using only decorators ? 我在这里缺少什么吗?还是仅使用装饰器解决方案?

You just need to squirrel away a copy of the passed-in function from inside your wrapper. 您只需要从包装器内松散传入函数的副本即可。 You could store the function references in a global name, in a list , a dict or any other way you choose. 您可以将函数引用存储为全局名称, listdict或您选择的任何其他方式。

Here is an example of MyScript.py that stores its function references in a dict : 这是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

After all of the initialization, you can invoke the functions thusly: 在完成所有初始化之后,您可以这样调用函数:

MyScript.funcs['preprocess']()

It seems like you are want to create some sort of function registry. 似乎您想创建某种功能注册表。 Here's a simple example implementation that uses a dictionary to keep track of the registered functions. 这是一个简单的示例实现,该实现使用字典来跟踪已注册的函数。

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

If you want to register an already defined function, you can use: 如果要注册已经定义的功能,可以使用:

tracker.register('A')(function_A)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM