【问题标题】:Python: Decorator Dispatcher: Catch-22Python:装饰器调度程序:Catch-22
【发布时间】:2018-06-04 15:02:39
【问题描述】:

我正在尝试构建一个基于装饰器的调度程序,例如您发现 Flask 或 Pyramid 使用的调度程序。我得到了一些有用的东西,但遇到了一些问题 22。以下代码有效,但仅仅是因为 foo() 被执行并设置了 .mq_path 属性。在启动应用程序并构建可调度函数列表时,尚未设置任何属性。我想执行由事件驱动的 foo()。

我可以“手动”提前准备函数列表并在添加函数时进行更新,但我喜欢 Flask 的工作方式,只需将装饰器添加到处理 URL(或在本例中为 MQ 路径)的函数中.

list_of_paths = []
path_dispatcher = {}

def handle_mq(path):
    def decorator(fn):
        def decorated(*args,**kwargs):
            decorated.mq_path = path
            print "Hello from the handle_mq() decorator, your path is: {0}".format(path)
            return fn(*args,**kwargs)
        return decorated
    return decorator

@handle_mq('/some/path')
def foo():
    print "foo!"

foo() # <- this code only works if I first call the decorated function

for k, v in globals().items():
    if hasattr(v, 'mq_path'):
        list_of_paths.append(v.mq_path)
        path_dispatcher[v.mq_path] = v

print list_of_paths
print path_dispatcher
path_dispatcher['/some/path']()

所以基本上问题是,如何在装饰函数首次执行之前收集它们的列表?

我使用的是 Python 2.7。

【问题讨论】:

  • 不确定我是否理解您要完成的工作,但如果您需要跟踪状态,您应该考虑将装饰器设为对象而不是函数。

标签: python python-decorators dispatch


【解决方案1】:

我找到了答案!

list_of_paths = []
path_dispatcher = {}

def handle_mq(path):
    def decorator(fn):
        list_of_paths.append(path)
        path_dispatcher[path] = fn
        def decorated(*args,**kwargs):
            print "Hello from handl_mq decorator, your path is: {0}".format(path)
            return fn(*args,**kwargs)
        return decorated
    return decorator

@handle_mq('/some/path')
def foo():
    print "foo!"

print list_of_paths
print path_dispatcher
path_dispatcher['/some/path']()

【讨论】:

    猜你喜欢
    • 2018-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-07
    • 2013-08-07
    • 2014-01-23
    相关资源
    最近更新 更多