具有实例级信息的Python装饰器
下面是一个不起作用的例子,它说明了我想要得到的东西具有实例级信息的Python装饰器,python,decorator,Python,Decorator,下面是一个不起作用的例子,它说明了我想要得到的东西 class TestClass(object): def require_debug_mode(self, f): def func_wrapper(*args, **kwargs): if self.debug_mode: return f(*args, **kwargs) return func_wrapper def __init_
class TestClass(object):
def require_debug_mode(self, f):
def func_wrapper(*args, **kwargs):
if self.debug_mode:
return f(*args, **kwargs)
return func_wrapper
def __init__(self, debug_mode):
self.debug_mode = debug_mode
@require_debug_mode
def print_message(self, msg):
print msg
您可以按照以下方式重新写入所需的打印消息
:
def print_message(self, msg):
if self.debug_mode:
print msg
我基本上希望能够修饰将执行某些检查的方法(而不必在可能使用它的每个方法中重复该检查)。但这些检查需要访问实例级信息。这是可能的吗?装饰器接收到与常规方法相同的参数,这意味着装饰器也可以使用
self
。代码的问题在于,您希望外部包装器也获得self
参数,但事实并非如此(它在声明时被调用,此时没有实例)
例如:
import functools
class TestClass(object):
def require_debug_mode(function):
@functools.wraps(function)
def _require_debug_mode(self, *args, **kwargs):
assert self.debug_mode, 'Debug mode is required for %r' % function
return function(self, *args, **kwargs)
return _require_debug_mode
def __init__(self, debug_mode):
self.debug_mode = debug_mode
@require_debug_mode
def print_message(self, msg):
print msg
test_class = TestClass(True)
test_class.print_message('ping')
test_class = TestClass(False)
test_class.print_message('pong')
输出:
ping
Traceback (most recent call last):
...
AssertionError: Debug mode is required for <function print_message at 0x...>
shell returned 1
ping
回溯(最近一次呼叫最后一次):
...
AssertionError:调试模式是必需的
壳返回1
装饰器是一个函数,给定一个函数作为输入,返回一个函数作为输出
您想输入一个函数print\u message(self,msg)
。那很好
为了使decorator有效地工作,结果函数必须具有类似的行为。因此,您需要包装函数,对足够的参数进行解码,以启用“窥视”以查看所需内容:
def func_wrapper(self, *args, **kwargs):
if self.debug_mode:
return self.f(*args, **kwargs)
要将装饰器作为类的一部分,可以使用以下代码:
class TestClass(object):
def require_debug_mode(f):
def func_wrapper(self, *args, **kwargs):
if self.debug_mode:
return f(self, *args)
return func_wrapper
def __init__(self, debug_mode):
self.debug_mode = debug_mode
@require_debug_mode
def print_message(self, msg):
print(msg)
tc_obj = TestClass(True)
tc_obj.print_message("debug msg")
# debug msg
tc_obj = TestClass(False)
tc_obj.print_message("debug msg")
# no output
要将装饰器保持在类之外,可以使用以下方法
def require_debug_mode(f):
def wrapper(*args):
if args[0].debug_mode:
return f(*args)
return wrapper
class TestClass(object):
def __init__(self, debug_mode):
self.debug_mode = debug_mode
@require_debug_mode
def print_message(self, msg):
print(msg)
tc_obj = TestClass(True)
tc_obj.print_message("debug msg")
# debug msg
tc_obj = TestClass(False)
tc_obj.print_message("debug msg")
# no output
是的,很容易做到。您刚刚将
self
参数放错了位置。内部函数需要self
参数。