我正在尝试创建一个行为类似于包装对象的包装类。到目前为止,我已经提出了以下代码:
import functools
import types
method_wrapper = type((None).__str__)
class Box:
def __new__(cls, obj):
attrs = {}
attr_names = dir(obj)
for attr_name in attr_names:
attr = obj.__getattribute__(attr_name)
if isinstance(attr, (types.MethodType, method_wrapper)):
"Attr is a bound method, ignore self"
@functools.wraps(attr)
def wrapped_attr(self, *args, **kwargs):
return attr(*args, **kwargs)
attrs[attr_name] = wrapped_attr
elif isinstance(attr, types.FunctionType):
"attr is a static method"
attrs[attr_name] = staticmethod(attr)
else:
"attr is a property"
attrs[attr_name] = attr
cls = type(type(obj).__name__,
(cls, type(obj)),
attrs)
return object.__new__(cls)
我尝试用以下方法进行测试:
if __name__ == '__main__':
x=Box(object())
然而,它出现以下错误消息:
TypeError: __init__() should return None, not 'NotImplementedType'
__init__
正在调度 isinstance(attr, (types.MethodType, method_wrapper))
,wrapped_attr
似乎已被执行。你知道为什么会这样吗?
答案 0 :(得分:1)
问题在于:
for ...:
attr = ...
...
def wrapped_attr(...):
..attr..
这不会按预期工作,因为attr
会被for
循环反弹到各种值。所有子函数都将看到最后一个值绑定,而不是它在循环迭代中的值。在这种情况下,按字母顺序排列的最后一个值是__subclasshook__
,当使用随机参数调用时,它往往会返回NotImplemented。