如何解决将装饰器类应用于另一个类的方法
我正在学习装饰器,我正在尝试做的是将一个简单的装饰器类应用于另一个类的方法,以用于理解和教育目的。
class decorators():
def __init__(self,func):
self.func = func
def __call__(self,*args,**kwargs):
print(f'this method has been decorated')
return self.func(self,**kwargs)
class Users():
def __init__(self,name,password,age,email):
self.name = name
self.password = password
self.age = age
self.email = email
@decorators
def login(self):
name = input('Enter your name')
password = input('Enter your password')
if name == self.name and password == self.password:
print("user logged in")
else:
print("wrong credentials")
@decorators
def show(self):
print(f'my name is {self.name} and my age is {self.age}')
user1 = Users('John','pass',20,'john@doe.com')
user1.login()
正如你所看到的,我只是想测试我是否可以构建这个装饰器类来调用用户类中的任何方法,例如 login() 和 show()。如上所述调用 user1.login() 时,出现此错误:
AttributeError Traceback (most recent call last)
<ipython-input-98-ed78c0a45454> in <module>
----> 1 user1.login()
<ipython-input-96-759e600a717b> in __call__(self,**kwargs)
5 def __call__(self,**kwargs):
6 print(f'this method has been decorated')
----> 7 return self.func(self,**kwargs)
8
9 class Users():
<ipython-input-96-759e600a717b> in login(self)
18 name = input('Enter your name')
19 password = input('Enter your password')
---> 20 if name == self.name and password == self.password:
21 print("user logged in")
22 else:
AttributeError: 'decorators' object has no attribute 'name'
我的想法是 User 实例没有传递给装饰器,因此装饰器对象没有 User 属性“name”。有没有办法做到这一点?
解决方法
您将 self
传递给 self.func
的第一个参数:return self.func(self,*args,**kwargs)
但 self
是 decorator
实例,而不是 {{1} 的实例},因此出现错误。
有多种方法可以完成这项工作。本质上,当通过 descriptor protocol
在该实例上调用该实例时,该实例作为第一个参数传递给该函数对象也就是说,函数对象是描述符,它们的 Users
方法部分地将实例应用于自身。因此,让您的自定义类像函数对象一样运行的最简洁方法是使您的 __get__
类成为描述符,复制函数对象的作用:
decorator
举个例子:
from types import MethodType
class decorators:
def __init__(self,func):
self.func = func
def __call__(self,**kwargs):
print(f'this method has been decorated')
return self.func(*args,**kwargs)
def __get__(self,obj,objtype=None):
if obj is None:
return self
return MethodType(self,obj)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。