Reputation: 4077
I've got this working for the most part. I want to have a class decorator (Decorator
class) that accepts arguments (greeting
and farewell
) that can be used to wrap a method on an object (an instance of Person
).
Everything is working fine, except... the original command function on the Person
class is never run! If I manually call the function using something like
output = getattr(instance, func.func_name)(command, *args, **kwargs)
I get infinite recursion.
How do I do this? The full code is listed below:
import functools
class Decorator(object):
def __init__(self, greeting, farewell, *args, **kwargs):
print "initing"
self.greeting = greeting
self.farewell = farewell
def __call__(self, func, *args, **kwargs):
print "CALLING"
@functools.wraps(func)
def wrapper(instance, command, *args, **kwargs):
return "%s, %s! %s!\n%s, %s!" % (
self.greeting,
instance.name,
command,
self.farewell,
instance.name
)
return wrapper
class Person(object):
def __init__(self, name):
self.name = name
@Decorator("Hello", "Goodbye")
def command(self, data):
return data + "LIKE A BOSS"
s = Person("Bob")
print s.command("eat food")
Actual output:
initing
CALLING
Hello, Bob! eat food!
Goodbye, Bob!
Expected output:
initing
CALLING
Hello, Bob! eat food LIKE A BOSS!
Goodbye, Bob!
Upvotes: 3
Views: 130
Reputation: 250991
You never called func
to get the original message:
def wrapper(instance, command, *args, **kwargs):
original_value = func(instance, command) #call func here
return "%s, %s! %s!\n%s, %s!" % (
self.greeting,
instance.name,
original_value,
self.farewell,
instance.name
)
Output:
initing
CALLING
Hello, Bob! eat food LIKE A BOSS!
Goodbye, Bob!
Upvotes: 4
Reputation: 2048
You must call func(data) somewhere in your wrapper to get the "LIKE A BOSS" result and add it to the expected output
Upvotes: 0