[英]Apply decorators class to methods of another class
我正在学习装饰器,我想做的是将一个简单的装饰器 class 应用于另一个 class 的方法,以用于理解和教育目的。
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,*args, **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()
正如你所看到的,我只是想测试我是否可以构建这个装饰器 class 来调用用户 class 中的任何方法,例如 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, *args, **kwargs)
5 def __call__(self, *args, **kwargs):
6 print(f'this method has been decorated')
----> 7 return self.func(self,*args, **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'
我的想法是用户实例没有传递给装饰器,因此装饰器 object 没有用户属性“名称”。 有没有办法做到这一点?
您将self
传递给self.func
的第一个参数: return self.func(self,*args, **kwargs)
但self
是一个decorator
实例,而不是Users
的实例,因此会出现错误。
有多种方法可以使这项工作。 本质上,当通过描述符协议在该实例上调用该实例时,该实例作为第一个参数传递给 function object
也就是说,function 对象是描述符,它们的__get__
方法将实例部分应用于自身。 So the cleanest way to make your custom class act like a function object is to make your decorator
class a descriptor, replicating what a function object does:
from types import MethodType
class decorators:
def __init__(self, func):
self.func = func
def __call__(self, *args, **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)
所以,举个例子:
>>> from types import MethodType
>>> class decorators:
... def __init__(self, func):
... self.func = func
... def __call__(self, *args, **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)
...
>>> class Foo:
... def __init__(self):
... self.bar = 42
... @decorators
... def frobnicate(self):
... return self.bar + 1
...
>>> Foo().frobnicate()
this method has been decorated
43
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.