Self в Python декораторы - PullRequest
       51

Self в Python декораторы

4 голосов
/ 04 декабря 2011

Я хочу декоратор, который бы добавил оформленную функцию в список, например:

class My_Class(object):

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

    @decorator
    def my_function(self)
       print 'Hi'

Я ожидаю, что my_function будет добавлен в self.list, но я просто не могу написать этот декоратор. Если я попытаюсь написать его внутри My_Class, то мне придется использовать @ self.decorator, а self не существует, поскольку мы находимся вне какой-либо функции. И если я попытаюсь записать его из My_Class, я не смогу извлечь себя из my_function.

Я знаю, что существуют довольно похожие вопросы, но они слишком сложны, и я просто изучаю python и декораторы.

Ответы [ 3 ]

5 голосов
/ 04 декабря 2011

Вы не можете получить доступ к 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, чтобы получить список декорированных функций.

4 голосов
/ 04 декабря 2011

Нет ничего особенного в написании декораторов для связанных функций (методы экземпляра). Например, этот простой пример отлично работает:

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
2 голосов
/ 04 декабря 2011

Ваш атрибут 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'
...