将参数传递给访问self vars的列表中的装饰器?

时间:2013-01-18 23:03:13

标签: python

如何使用self修改decorator变量?

实施例

class Foo:
   def __init__(self,a):
       self.a = a
       self.li = []

    def afunction(self):
       pass

我想将函数对象afunction添加到列表self.li中,以便我可以在列表中调用它。防爆。有一个由类定义的函数列表。我该怎么做?

由于

3 个答案:

答案 0 :(得分:3)

我认为你不需要装饰师。函数是Python中的第一类对象:

class Foo:
   def __init__(self,a):
       self.a = a
       self.li = [self.afunction]

    def afunction(self):
       pass

答案 1 :(得分:2)

如果您打算将某个类的某些函数标记为特殊类型,以便稍后可以为其他目的识别它们,则可以使用装饰器,或者只使用命名约定。

def marked(function):

    function.marked = 1
    return function

class MarkAware(object):

    def run_marked(self, *args, **kwargs):
        for name in dir(self):
            meth = getattr(self, name)
            if hasattr(meth, 'marked'):
                meth(*args, **kwargs)

    def foo(self):
        pass

    @marked
    def bar(self):
        pass

替代:

class NameConvention(object):

     def run_batchable(self, *args, **kwargs):
         for name in dir(self):
             if name.startswith('batchable_'):
                 getattr(self, name)(*args, **kwargs)

     def foo(self):
         pass

     def batchable_bar(self):
         pass

答案 2 :(得分:1)

正如Lattyware在对unutbu的答案的评论中解释的那样,你不能直接做你所要求的,因为afunction上的任何装饰器将在创建类本身时运行,而不是在每个实例都是创建

如果您真正想要的是“由班级定义的功能列表”,那么您根本不需要任何花哨的东西。只需在__init__中创建该列表:

def __init__(self, a):
    self.a = a
    self.li = [f for f in dir(self) if inspect.ismethod(f)]

如果你想要一个特定功能的列表,最简单的方法是unutbu建议的方式,它仍然不需要装饰器。

如果您希望装饰者只是标记“此方法应该进入li”,请参阅sr2222的答案。

这些都不是你要求的,但它们可能就是你想要的。有几种方法可以实际使用装饰器将函数添加到self.li,但它们都非常糟糕,你可能不想要它们。例如:

class Foo:
    def __init__(self,a):
        self.a = a
        self.li = []

        def mydecorator(f):
            self.li.append(f)
            return f

        @mydecorator
        def afunction(self):
            print('a')
        self.afunction = new.instancemethod(afunction, self, Foo)