2

Let's say I have this class:

class Dumb:
    def __init__(self):
        self.x = "beautiful attribute"

    def do_something(self):
        print("awesome method") 

I know that I can get the value of the attribute x by using getattr(obj,"x") and I know that I can get a reference to the object from a method using method.__self__, like this:

duh = Dumb()
getattr(duh,"x")
object = duh.do_something.__self__
getattr(object,"x")

I'm using repl.it to show some snippets to a friend. It's convenient since it executes the script in the browser, but I can't use pdb for debugging. So, I thought I could use a decorator to obtain some info about the attributes of the object when one of his methods is executed:

def info(attribute):
    def wrap_gen(func):
        def wrapper(*args,**kwargs)
            object = func.__self__
            value = getattr(object,attribute)
            func(*args,**kwargs)
            print("The attribute %s is %s"%(attribute,value))
        return wrapper
   return wrap_gen

And then use it to decorate do_something in Dumb. However, it doesn't work,since it raises the exception:

AttributeError: 'function' object has no attribute '__self__'

If I understand this correctly, it's because when the decorator... decorates the method, there is no istance of Dumb (there is no class at all) and so, the method doesn't have any reference to that.

How can I accomplish such a task? A possible workaround could be write and test the snippet on my computer (so I can debug it properly), and then copy&paste the snippet, but it's a little bit cumbersome.

EDIT: I finally found what I was looking for, it's even simpler then what I tried:

Python decorator accessing class arguments

Basically, I have to explicitly pass self as an argument to the wrapper of the function, and then use it as a reference:

def info(attribute):
        def wrap_gen(func):
            def wrapper(self,*args,**kwargs)
                value = getattr(self,attribute)
                func(self,*args,**kwargs)
                print("The attribute %s is %s"%(attribute,value))
            return wrapper
       return wrap_gen
Russell Teapot
  • 511
  • 1
  • 6
  • 19

0 Answers0