Self in python decorators

I want the decorator to add a decorated function to the list, for example:

class My_Class(object): def __init__(self): self.list=[] @decorator def my_function(self) print 'Hi' 

I expect my_function to be added to self.list, but I just can't write this decorator. If I try to write it inside My_Class, then I have to use @ self.decorator, and self does not exist, since we are outside of any function. And if I try to write it from My_Class, then I cannot get self from my_function.

I know pretty similar questions, but they are too complicated, and I'm just learning python and decorators.

+4
source share
3 answers

You cannot access self from the decorator because the decorator is started during function definition, and there are no instances of My_Class at that time.

It is better to put the list of functions as an attribute of the class instead of an instance attribute. Then you can pass this list as a parameter to the decorator:

 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 

Now you can access MyClass.funcList to get a list of decorated functions.

+5
source

There is nothing special about writing decorators for related functions (instance methods). For example, this simple example works fine:

 def decorator(fn): print "I'm decorating!" return fn class MyClass(object): def __init__(self): self.list = [] @decorator def my_function(self): print "Hi" 

If you want to use self in your decorator, you will treat your decorator as you would any decorator that uses the args function:

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

The list attribute must be a class attribute (and it needs to be renamed since list is a built-in type). Then you can do something like this:

 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' 
+2
source

Source: https://habr.com/ru/post/1384579/


All Articles