【问题标题】:Get python decorator arguments at run time在运行时获取 python 装饰器参数
【发布时间】:2016-04-26 18:44:49
【问题描述】:

有什么方法可以在运行时获取装饰器函数的参数吗?我正在从事的项目非常庞大,重写受影响的代码将是一项巨大的努力。我需要一个动态解决方案来列出分配给功能列表的所有“类别”。为此,我想避免超级 hacky 的解决方案,比如通过我的所有模块进行正则表达式。这可以通过检查调用堆栈中的帧来完成吗?

在我们的环境中,函数是对象方法,我们也使用链式装饰器。为了便于理解,我把这段代码放在一起。

如果这是不可能的,我可以为项目的一部分组合另一个装饰器,尽管它会增加更多的复杂性。但是欢迎任何解决我的问题的建议。

def check(*args):
    # do something project relevant, so just return True
    return True

def decorate(*categories):
    def wrap(f):
        def wrap_check_categories(*args, **kwargs):
            if check(*categories):
                return f(*args, **kwargs)
            else:
                raise Exception
        return wrap_check_categories
    return wrap

def get_categories(f):
    '''Returns decorator parameters'''
    # ... do some magic here
    raise NotImplementedError

@decorate('foo', 'bar')
def fancy_func(*args, **kwargs):
    return args, kwargs

def main():
    ## should output ['foo', 'bar']
    print get_categories(fancy_func)

if __name__ == '__main__':
    main()

【问题讨论】:

    标签: python python-2.7 introspection python-decorators


    【解决方案1】:

    修改装饰器以将类别存储在装饰函数的属性(例如_args)中:

    def check(*args):
        # do something project relevant, so just return True
        return True
    
    def decorate(*categories):
        def wrap(f):
            def wrap_check_categories(*args, **kwargs):
                if check(*categories):
                    return f(*args, **kwargs)
                else:
                    raise Exception
            wrap_check_categories._args = categories    # <-- store the categories
            return wrap_check_categories
        return wrap
    
    def get_categories(f):
        '''Returns decorator parameters'''
        # ... do some magic here
        return f._args
    
    @decorate('foo', 'bar')
    def fancy_func(*args, **kwargs):
        return args, kwargs
    
    def main():
        ## should output ['foo', 'bar']
        print get_categories(fancy_func)
    
    if __name__ == '__main__':
        main()
    

    产量

    ('foo', 'bar')
    

    【讨论】:

      猜你喜欢
      • 2018-01-21
      • 1970-01-01
      • 1970-01-01
      • 2010-11-03
      • 2017-08-20
      • 1970-01-01
      • 1970-01-01
      • 2013-06-03
      • 1970-01-01
      相关资源
      最近更新 更多