Question
How do I pass a object field to a decorator on a class method as an argument? What I want to do is something like:
- test3836.py
- #!/usr/bin/env python
- import functools
- def check_authorization(*args, **kw):
- print "Doing authorization"
- for a in args:
- print "\t%s" % (a)
- def wrapper(f):
- def dfun(*args, **kw):
- result = f(*args, **kw)
- return result
- return dfun
- return wrapper
- class Client(object):
- def __init__(self, url):
- self.url = url
- @check_authorization('some_attr', "self.url")
- def get(self):
- print "Get"
- self.do_work()
- def do_work(self):
- print "Doing work"
- client = Client("http://test.org")
- client.get()
How-To
Instead of passing in the instance attribute at class definition time, check it at runtime:
- #!/usr/bin/env python
- import functools
- def check_authorization(*args, **kw):
- for a in args:
- print "Decorator argu=%s" % (a)
- def wrapper(f):
- def dfun(*args, **kw):
- print "Doing authorization on URL=%s" % (args[0].url) # args[0] -> self
- result = f(*args, **kw)
- return result
- return dfun
- return wrapper
- class Client(object):
- def __init__(self, url):
- self.url = url
- @check_authorization('some_attr')
- def get(self):
- print "Get"
- self.do_work()
- def do_work(self):
- print "Doing work"
- client = Client("http://test.org")
- client.get()
The decorator intercepts the method arguments; the first argument is the instance, so it reads the attribute off of that. You can pass in the attribute name as a string to the decorator and use getattr if you don't want to hardcode the attribute name:
- #!/usr/bin/env python
- import functools
- def check_authorization(*dargs, **dkw):
- for a in dargs:
- print "Decorator argu=%s" % (a)
- def wrapper(f):
- def dfun(*args, **kw):
- print "Doing authorization on URL=%s" % (getattr(args[0], dargs[0]))
- result = f(*args, **kw)
- return result
- return dfun
- return wrapper
- class Client(object):
- def __init__(self, url):
- self.url = url
- @check_authorization('url')
- def get(self):
- print "Get"
- self.do_work()
- def do_work(self):
- print "Doing work"
- client = Client("http://test.org")
- client.get()
Supplement
* [Python 學習筆記] 進階議題 : 修飾器 (函式修飾器)
* [ Python 文章收集 ] Decorators I: Introduction to Python Decorators
沒有留言:
張貼留言