我正在尝试实现这个:How to fake type with Python。我正在包装一些我不控制的.NET对象,所以不希望包装器中的类实例化对它们调用__new__
。我从上面的问题中获取了代码,并构建了一个简单的示例:
class WrappableInt(object):
def __new__(cls,*args,**kwargs):
print("Making a new wrapint")
return super().__new__(cls)
def __init__(self,x):
self.x=x
def wrap_user(wrapee):
class wrapped_user(type(wrapee)):
def __new__(cls,*args,**kwargs):
return object.__new__(cls)
def __init__(self):
pass
def gimmieFive(self):
return 5
def __getattribute__(self, attr):
self_dict = object.__getattribute__(type(self), '__dict__')
if attr in self_dict:
return self_dict[attr]
return getattr(wrapee, attr)
return wrapped_user()
当我运行以下测试时,一切如预期:
^{pr2}$但是,当我运行gimmieFive时,我得到以下结果:
>>> p.gimmieFive()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: gimmieFive() missing 1 required positional argument: 'self'
为什么python认为gimmieFive
是静态方法,而它似乎知道{
>>> p.gimmieFive(1)
5
你在这里绕过了正常的descriptor protocol。
__getattribute__
不仅仅是查找类上的名称,如果检索到的对象支持绑定,它还会绑定它们。在Python函数对象是描述符,将它们绑定到实例会生成一个方法对象,当调用该对象时,该对象作为第一个函数参数传入绑定实例。返回原始的未绑定函数对象。在
重新实现绑定行为是。。复杂。如果实例属性和从类中检索的描述符对象之间发生冲突,则需要检查本地属性,确定描述符是数据描述符还是正则描述符,并决定返回哪个。在
简单而基本的实现至少需要支持
__get__
绑定:这对于您的用例来说已经足够了,因为您的
wrapped_user
类现在没有任何数据描述符。在通过上述更改,您的具体示例如预期般工作:
^{pr2}$相关问题 更多 >
编程相关推荐