如何解决类型错误:“dict”对象的描述符“值”不适用于“类型”对象
我制作了一个装饰器,它可以修改一个类,以便除 init
或 class
之外的任何方法在运行之前打印“Hello World”。问题是我从 dict
继承时不断收到意外错误消息。这是什么意思,我该如何解决?
from functools import wraps
# Print hello world when any method is called
def hello_world(cls):
for attr in dir(cls):
# Only modify methods that aren't init or class
if not callable(getattr(cls,attr)) or any([method in attr for method in ["init","class"]]):
continue
old_method = getattr(cls,attr)
# Modify method to print "Hello World" before running
@wraps(getattr(cls,attr))
def new_method(self,*args,**kwargs):
print("Hello World!")
return old_method(self,**kwargs)
# Update class with modified method
setattr(cls,attr,new_method)
return cls
@hello_world
class Custom(dict):
pass
dictionary = Custom()
dictionary["Key"] = "Value"
print(dictionary)
世界你好!
回溯(最近一次调用最后一次):
文件“”,第 22 行,在
字典 = 自定义()
文件“”,第 12 行,在 new_method
返回 old_method(self,**kwargs)
类型错误:“dict”对象的描述符“值”不适用于“类型”对象
解决方法
多亏了 Tim Roberts 的洞察力,我才能够拼凑出解决问题的方法。我不得不向排除列表添加更多属性以避免无限递归,并且我添加了一个额外的调试语句,以便您可以在打印“Hello world!”时看到正在调用哪个方法。
无论如何,以下工作:
from functools import wraps
# Print hello world when any method is called
def hello_world(cls):
for attr in dir(cls):
# Only modify methods that aren't init or class
if not callable(getattr(cls,attr)):
continue
if attr in ("__class__","__subclasshook__","__init__","__init_subclass__","__str__","__repr__"):
continue
old_method = getattr(cls,attr)
def do_override(cls,attr,old_method):
# Modify method to print "Hello World" before running
@wraps(getattr(cls,attr))
def new_method(self,*args,**kwargs):
print("Hello World!")
print("attr:",attr)
return old_method(self,**kwargs)
# Update class with modified method
setattr(cls,new_method)
do_override(cls,old_method)
return cls
@hello_world
class Custom(dict):
pass
dictionary = Custom()
dictionary["Key"] = "Value"
print(dictionary)
运行时,它产生:
Hello World!
attr: __new__
Hello World!
attr: __setitem__
{'Key': 'Value'}
do_override
函数捕获 cls
、attr
和 old_method
的值,以便后续循环迭代不会影响之前的
绑定值。
在输出中,第一个方法调用来自创建类实例时,第二个来自设置值时。
这可能需要做一些工作才能满足您的需求,您可能需要向排除列表添加一些额外的属性,但这应该能让您解决遇到的问题。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。