如何解决如何使用代码块装饰实例并访问/使用实例的变量?
我尝试为实例(不是类)的方法构建一个装饰器,它可以灵活地将代码块放在方法的前面和/或后面(而不影响其他实例)。直到我下面的代码有效:
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,after = None):
def wrap(self,*args,**kwargs):
if before: before() # code block insert
print(self.name) # --> even this DOES NOT WORK!
result = func(self,**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()
感谢任何解决方案,并在此先感谢!
解决方法
from functools import wraps
def Decorate(func,before = None,after = None):
@wraps(func)
def wrap(*args,**kwargs):
if before: before() # code block insert
result = func(*args,**kwargs)
if after: after() # code block insert
return result
return wrap
def Before():
print('before')
def After():
print('after')
class Test():
def __init__(self,name):
self.name = name
def put(self,prefix):
print(prefix,self.name)
put = Decorate(put,Before,After)
a = Test('me')
a.put("pre")
你可以在你的类中执行你的装饰器。在您的 wrap
中,通过 func
将您获得的任何内容传递给 (*args,**kwargs)
。 self
仍然是 args
中隐含的第一个参数。
编辑:评论中与代码相关的问题
from functools import wraps
def Before(t):
print('before')
print(t.name)
def After(t):
print('after')
print(t.name)
def Decorate(func,**kwargs):
if before: before(args[0]) # code block insert
result = func(*args,**kwargs)
if after: after(args[0]) # code block insert
return result
return wrap
class Test():
def __init__(self,self.name)
put = Decorate(put,After)
a = Test('me')
a.put("pre")
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。