我如何获得函数的装饰器?

时间:2014-01-10 16:11:29

标签: python cmd

我有一个名为WindCMD的类,它具有装饰器的功能

@options( 
             [
              make_option( '-s', '--windspeed',
                           default = 999,
                           help = "Set the wind speed." 
                           ),

              make_option( '-d', '--winddir',
                           default = 999,
                           help = "Set the wind direction." 
                           )                            
              ] 
             )     
def do_set_wind_manually( self, line, opts = None ):

使用__dict__可以获得类的所有功能,但是如何获得函数装饰器和选项呢?

1 个答案:

答案 0 :(得分:2)

你不能一般。装饰器只对函数执行预处理步骤。装饰器返回的对象可能甚至不是您定义的原始函数(在大多数情况下,它不包含函数)。一旦装饰器完成了它的工作,返回的函数上没有留下显式的记录,它是某个其他函数的装饰器的结果。你可以定义一个装饰器,它在函数上设置一些属性。例如:

class options(object):
    def __init__(self, somearg):
        self.somearg = somearg

    def __call__(self, func):
        func.options = self
        return func

>>> @options('foo')
... def myfunc(): pass
...
>>> myfunc.options
... <__main__.options at 0x19f6d90>
>>> myfunc.options.somearg
... 'foo'

我想如果你真的需要,你也可以写一个包装装饰器并记录它们的装饰器。这只是这个想法的粗略实现:

class record_decorator(object):
    def __init__(self, decorator):
        self.decorator = decorator

    def __call__(self, func):
        result = self.decorator(func)
        if not hasattr(result, 'decorators'):
            if hasattr(func, 'decorators'):
                result.decorators = func.decorators[:]  # copy
            else:
                result.decorators = []
        result.decorators.append(self.decorator)
        return result

>>> def a(func):
...     print 'decorating with a'
...     return func
...
>>> def a(func):
...     print 'decorating with a'
...     return func
...
>>> @record_decorator(b)
... @record_decorator(a)
... def myfunc(): pass
...
decorating with a
decorating with b
>>> myfunc.decorators
[<function __main__.a>, <function __main__.b>]

现在myfunc.decorators包含按照应用顺序应用于函数的所有装饰器的列表。至少在原则上 - 它仍然不会告诉你任何使用record_decorator 在没有的情况下应用的装饰器。