【问题标题】:Decorator/wrapper: How to deal with arguments after positional/keyword args are all assigned to wrapped function's parameters?装饰器/包装器:位置/关键字参数全部分配给包装函数的参数后如何处理参数?
【发布时间】:2014-10-04 11:49:59
【问题描述】:

我想知道 Python 中是否有一种方法可以让包装器在函数的参数已经被解析为参数后访问它们。因此,例如,我想包装两个具有不同(数量)参数的函数:

def fn_1(a, b=None, config=None):
    ...

def fn_2(b=None, config=None):
    ...

我希望 like 让我的包装器查看 config 是否有值,如果没有,则从其他地方加载它:

class with_config(object):
    def __init__(self, f):
       self.f = f
    def __call__(self, *args, **kwargs):
       if config not in kwargs:
           kwargs[config] = load_config_from_some_default_location()

但我不知道如何确定config 是否已按位置传递,因为它在args 列表中的位置可能因函数而异。

如果我可以得到参数之后,位置参数已根据参数命名(例如,第一个位置分配给a,第二个分配给b,第三个分配给@987654329 @) 我会没事的。

情况比这稍微复杂一些,但我认为这解决了我的问题。

有什么建议吗?

【问题讨论】:

  • 我不知道我是怎么错过this similar post 的,但我猜这是我能做的最好的了。任何有更多想法的人都可以加入。

标签: python arguments wrapper decorator


【解决方案1】:

这可能对你有帮助:

import inspect

def func(a, b=None, config=None):
    args, _, _, values = inspect.getargvalues(inspect.currentframe())
    print args # prints 'a', 'b', 'config'
    print values # prints {'a':12, 'b':None, 'config':None}
    if values['config'] == None:
        # Load config from somewhere else

if __name__ == '__main__':
    func(12)

【讨论】:

  • 这在您展示的情况下效果很好!在包装器的情况下,我认为它不会起作用,因为该框架的参数是传递给包装器的参数,而不是传递给原始的参数。我有兴趣通过分析另一个框架或其他东西来看看这是否有效?我需要查看检查文档
  • 啊哈!如果我们使用inspect.getargspec(self.f)[0] 来获取ArgSpec,就像您在此处所做的那样,然后将它们与传递给__call__args 列表一起压缩,那么一切都是肉汁
【解决方案2】:

我终于和this solution from Nadia Alramli一起去了:

class with_config(object): def __init__(self, f): self.f = f def __call__(self, *args, **kwargs): kwargs.update(dict(zip(self.f.func_code.co_varnames, args))) if config not in kwargs: kwargs[config] = load_config_from_some_default_location() return self.f(**kwargs)

【讨论】:

    猜你喜欢
    • 2011-06-25
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 2016-09-27
    • 2010-10-14
    • 2014-05-01
    • 2016-01-30
    • 2015-09-03
    相关资源
    最近更新 更多