Python伪装类型(续)

2024-09-28 18:53:44 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试实现这个: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

Tags: selfnewreturnobjectdeftypeargsdict
1条回答
网友
1楼 · 发布于 2024-09-28 18:53:44

你在这里绕过了正常的descriptor protocol__getattribute__不仅仅是查找类上的名称,如果检索到的对象支持绑定,它还会绑定它们。在

Python函数对象是描述符,将它们绑定到实例会生成一个方法对象,当调用该对象时,该对象作为第一个函数参数传入绑定实例。返回原始的未绑定函数对象。在

重新实现绑定行为是。。复杂。如果实例属性和从类中检索的描述符对象之间发生冲突,则需要检查本地属性,确定描述符是数据描述符还是正则描述符,并决定返回哪个。在

简单而基本的实现至少需要支持__get__绑定:

if attr in self_dict:
    obj = self_dict[attr]
    if hasattr(obj, '__get__'):
        obj = obj.__get__(self, type(self))
    return obj

这对于您的用例来说已经足够了,因为您的wrapped_user类现在没有任何数据描述符。在

通过上述更改,您的具体示例如预期般工作:

^{pr2}$

相关问题 更多 >