Python 装饰器中的 self

9 投票
4 回答
8857 浏览
提问于 2025-04-17 07:39

我想要一个装饰器,它可以把被装饰的函数添加到一个列表里,像这样:

class My_Class(object):

    def __init__(self):
        self.list=[]

    @decorator
    def my_function(self)
       print 'Hi'

我希望我的函数能被添加到self.list里,但我就是写不出这个装饰器。如果我试着在My_Class里面写这个装饰器,那我就得用@self.decorator,但因为我们不在任何函数里面,所以self是不存在的。如果我试着在My_Class外面写,那我就无法从my_function中获取self。

我知道有类似的问题,但那些都太复杂了,而我只是刚开始学习python和装饰器。

4 个回答

2

你的 list 属性应该是一个类的属性(而且应该改个名字,因为 list 是一个内置类型)。这样你就可以像下面这样做:

my_methods = []

def my_method(method):
    my_methods.append(method)
    return method


class MyClass(object):

    my_methods = my_methods

    @my_method
    def my_function(self):
       print 'Hi'
3

为绑定函数(也就是实例方法)编写装饰器其实没什么特别的。比如,这个简单的例子就很好用:

def decorator(fn):
    print "I'm decorating!"
    return fn


class MyClass(object):
    def __init__(self):
        self.list = []

    @decorator
    def my_function(self):
        print "Hi"

如果你想在装饰器中使用 self,那么你就要像对待其他使用函数参数的装饰器一样来处理你的装饰器:

def decorator(fn):
    def _decorator(self):
        print "I'm decorating, and here's my list: %s!" % self.list
        return fn(self)
    return _decorator
14

你不能在装饰器中访问 self,因为装饰器是在函数定义的时候运行的,而那个时候还没有 My_Class 的实例。

把函数列表放在类属性中,而不是实例属性中,这样更好。然后你可以把这个列表作为参数传给装饰器:

def addToList(funcList):
    '''Decorator that adds the function to a given list'''
    def actual_decorator(f):
         funcList.append(f)
         return f
    return actual_decorator

class MyClass(object):
    funcList = []

    @addToList(funcList)
    def some_function(self, name):
        print 'Hello,', name

现在你可以通过 MyClass.funcList 来获取被装饰的函数列表。

撰写回答