简体   繁体   English

为什么我不能覆盖这个魔术方法?

[英]Why Can't I Override this Magic Method?

I was working on making a wrapper object that would take an instance of an arbitrary class and then automatically wrap all of its own magic methods to simply use the magic method (and value) of the wrapped object.我正在制作一个包装对象,该对象将采用任意类的实例,然后自动包装所有自己的魔术方法,以简单地使用包装对象的魔术方法(和值)。 For some reason, this doesn't work:出于某种原因,这不起作用:

class Wrapper:
    def __init__(self, wrapped):
        self.wrapped = wrapped
        for method in filter(lambda x: x.startswith("__") and (x not in 
        ["__init__", "__new__", "__class__", "__metaclass__"]), 
        dir(wrapped)):
            if hasattr(getattr(wrapped, method), "__call__"):
                new_func = functools.partial(getattr(type(wrapped), method), self.wrapped)
                setattr(self, method, new_func)


t = Wrapper(7)
t + 8
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  TypeError: unsupported operand type(s) for +: 'Wrapper' and 'int'

class Tester:
    def __init__(self):
        self.v = 5
    def __add__(self, other):
        return self.v + other

y = Tester()
y + 7
12
t = Wrapper(y)
t + 9
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'Wrapper' and 'int'

9 + t
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'Wrapper'

t.__add__
functools.partial(<function Tester.__add__ at 0x7fbec6372170>, <__main__.Tester object at 0x7fbec6392990>)

t.__add__(7)
12

I thought maybe the partial wasn't working properly with the distinction between the type's method and an instance method, but when I directly call my wrapper's magic add, it works properly.我想也许由于类型方法和实例方法之间的区别,部分无法正常工作,但是当我直接调用我的包装器的魔术添加时,它可以正常工作。 (This is tested in CPython 3.3) (这是在 CPython 3.3 中测试的)

Special methods are always looked up on the type of the instance (here the class object), not on the instance.特殊方法总是在实例的类型(这里是类对象) 上查找,而不是在实例上查找 Otherwise a __repr__ on a class would be used when you tried to print the representation of the class itself;否则,当您尝试打印类本身的表示时,将使用类上的__repr__ type(class).__repr__(class) would use the correct magic method, while class.__repr__() would raise an exception because self was not provided. type(class).__repr__(class)会使用正确的魔法方法,而class.__repr__()会引发异常,因为没有提供self

You'll need to implement these special methods directly on the wrapper, propagating any exceptions that might be raised when called on the wrapped object.您需要直接在包装器上实现这些特殊方法,传播在被包装的对象上调用时可能引发的任何异常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM