Dot operator magic has me stymied...

C

Casey Rodarmor

Hi All,

I'm trying to use a class as a decorator for another class method, but
it's giving me a lot of grief. Basically, my problem is with the
example below:
.... def __init__(self, function):
.... self.function = function
....
.... def __call__(self, *args, **kwargs):
.... self.function(*args, **kwargs)
........ def __init__(self):
.... self.msg = "Hello,"
....
.... @decorator
.... def greet(self, name):
.... print self.msg, name
....Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "decorate.py", line 6, in __call__
self.function(*args, **kwargs)
TypeError: greet() takes exactly 2 arguments (1 given)


I'm guessing that using a decorator that returns a class instance
instead of a function instance has messed up the magic of the dot
operator, causing it not to bind the foo instance to the self
argument.

Can anybody shed some light on what's happening here?

Also, I really do like using classes as decorators. Are there any
workarounds to get it to work with methods?

Thanks a bunch!

Best regards,
Casey Rodarmor
 
A

Arnaud Delobelle

Hi All,

I'm trying to use a class as a decorator for another class method, but
it's giving me a lot of grief. Basically, my problem is with the
example below:


...     def __init__(self, function):
...         self.function = function
...
...     def __call__(self, *args, **kwargs):
...         self.function(*args, **kwargs)
...>>> class Foo:

...     def __init__(self):
...         self.msg = "Hello,"
...
...     @decorator
...     def greet(self, name):
...         print self.msg, name
...>>> foo = Foo()

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "decorate.py", line 6, in __call__
    self.function(*args, **kwargs)
TypeError: greet() takes exactly 2 arguments (1 given)

I'm guessing that using a decorator that returns a class instance
instead of a function instance has messed up the magic of the dot
operator, causing it not to bind the foo instance to the self
argument.

Can anybody shed some light on what's happening here?

When

@decorator
def greet(self, name):
print self.msg, name

is executed, a new decorator object is created whose function
attribute is the function 'greet' above (with two arguments) and the
result is given the name 'greet'.

Later, when

is executed,

foo.greet is a decorator object whose attribute 'function' is the
plain function 'greet'. So it expects two arguments and you only
provide one.

To fix this you could use the Descriptor protocol. If you don't know
what it is, I suggest you read this:

http://users.rcn.com/python/download/Descriptor.htm

It should give you what you need to get it right.

HTH
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,140
Latest member
SweetcalmCBDreview
Top