Reputation: 59
I am trying to create a decorator that will validate if the parameter exist and retrieve the name of the method that is decorated.
I was able to access the name of the method in my second layer of the function but not the first.
For example, I have this decorator
def p_decorate(name, *a, **k):
print(name + ' is at object: ')
print a #I would like to get the method object here
def fn(*a, **k)
print a #object prints here instead
return fn
return p_decorate
I have this class I would like to decorate
class Person(object):
@p_decorate('John')
def get_fullnameobject(self):
return self.name
I expect it to print:
John is at object: (<function get_fullnameobject at 0x000000003745A588>,)
(<function get_fullnameobject at 0x000000003745A588>,)
but the output is:
John is at object: ()
(<function get_fullnameobject at 0x000000003745A588>,)
Upvotes: 1
Views: 221
Reputation: 1
You can use function.__name__
to get the name of the function. So in your case it would be:
print(name.__name__ + ' is at object: ')
Upvotes: 0
Reputation: 531085
You need another nested function to define a decorator that takes arguments.
def p_decorate(name):
def _(f):
print(name + ' is at object: ')
print f
def fn(*a, **k):
# Do something, but ultimately you probably want to call f
...
return fn
return _
p_decorate("John")
returns the actual decorator, which takes get_fullnameobject
as its f
argument and returns the new fn
object to bind to get_fullnameobject
. Without decorator syntax, the usage looks like
def get_fullnameobject(self):
return self.name
get_fullnameobject = p_decorate("John")(get_fullnameobject)
Upvotes: 1
Reputation: 42007
The function p_decorate
is being called with only argument John
(*a
and **k
both will be empty), hence you're getting an empty tuple for a
.
Just to note, the returned fn
callable is being called with the get_fullnameobject
callable afterwards.
More importantly, your current implementation is incomplete as you can never call the method -- you need another closure to actually do that.
Upvotes: 1