【发布时间】:2021-04-23 21:00:51
【问题描述】:
我尝试为实例(不是类)的方法构建一个装饰器,它可以灵活地将代码块放在方法的前面和/或后面(并且不影响其他实例)。直到我的以下代码有效:
def Decorate(func, before = None, after = None):
def wrap(*args, **kwargs):
if before: before() # code block insert
result = func(*args, **kwargs)
if after: after() # code block insert
return result
return wrap
class Test():
def __init__(self, name):
self.name = name
def put(self, prefix):
print(prefix, self.name)
a = Test('me')
def Before():
print('before')
def After():
print('after')
a.put = Decorate(a.put, Before, After)
a.put('it is')
如何扩展访问/使用实例的变量和方法的代码块?这方面的代码示例如下所示:
def Before():
print('before')
print(self.name)
self.any_method(any_argument) # just an example!
我已经尝试了几件事,但都没有成功。而且我已经很难直接在包装器中访问实例值:
def Decorate(func, before = None, after = None):
def wrap(self, *args, **kwargs):
if before: before() # code block insert
print(self.name) # --> even this DOES NOT WORK!
result = func(self, *args, **kwargs)
if after: after() # code block insert
return result
return wrap
这里print(self.name) 抛出错误:AttributeError: 'str' object has no attribute 'name'。所以看起来我在下面的代码块之一(Before() & After())中使用相同的注释还很遥远。
一个补充:当我向实例添加方法时,该方法有效: 此方法在类中(因此用于处理字符串和 exec,但可以将名称作为字符串或函数本身传递):
def addMethod(self, method, givenName = ''):
print('add')
if givenName == '':
N = method.__name__
else:
N = givenName
self._methods.append(N)
exec('self.' + N + ' = ' + method.__name__ + '.__get__(self)')
主要部分的代码如下所示:
def x(self):
print('hello,', self.name)
a.addMethod(x)
a.x()
感谢任何解决方案,并提前非常感谢!
【问题讨论】:
标签: python oop instance decorator wrapper