如何将类字段作为参数传递给类方法上的装饰器?我想要做的是:
class Client(object):
def __init__(self, url):
self.url = url
@check_authorization("some_attr", self.url)
def get(self):
do_work()
它抱怨self不存在用于将self.url
传递给装饰器的功能。有什么办法可以解决这个问题吗?
发布于 2012-07-31 07:38:54
是。不是在类定义时传入实例属性,而是在运行时检查它:
def check_authorization(f):
def wrapper(*args):
print args[0].url
return f(*args)
return wrapper
class Client(object):
def __init__(self, url):
self.url = url
@check_authorization
def get(self):
print 'get'
>>> Client('http://www.google.com').get()
http://www.google.com
get
装饰器截获方法参数;第一个参数是实例,因此它读取该实例的属性。如果不想硬编码属性名,可以将属性名作为字符串传递给装饰器,并使用getattr
:
def check_authorization(attribute):
def _check_authorization(f):
def wrapper(self, *args):
print getattr(self, attribute)
return f(self, *args)
return wrapper
return _check_authorization
发布于 2016-04-30 02:13:03
一个更简洁的示例可能如下所示:
#/usr/bin/env python3
from functools import wraps
def wrapper(method):
@wraps(method)
def _impl(self, *method_args, **method_kwargs):
method_output = method(self, *method_args, **method_kwargs)
return method_output + "!"
return _impl
class Foo:
@wrapper
def bar(self, word):
return word
f = Foo()
result = f.bar("kitty")
print(result)
它将打印:
kitty!
发布于 2019-05-27 17:10:17
另一种选择是放弃语法糖,在类的__init__
中进行修饰。
def countdown(number):
def countdown_decorator(func):
def func_wrapper():
for index in reversed(range(1, number+1)):
print(index)
func()
return func_wrapper
return countdown_decorator
class MySuperClass():
def __init__(self, number):
self.number = number
self.do_thing = countdown(number)(self.do_thing)
def do_thing(self):
print('im doing stuff!')
myclass = MySuperClass(3)
myclass.do_thing()
它将打印
3
2
1
im doing stuff!
https://stackoverflow.com/questions/11731136
复制相似问题