numpy.ndarray的python运算符就像类一样

时间:2017-05-20 18:14:36

标签: python numpy

我有一个类,它有一个numpy.ndarray作为成员,并且通过重载__getitem____getattr__来表现类似于ndarray:

class Foo(object):
    def __init__(values):
        # numpy.ndarray
        self._values = values

    def __getitem__(self, key):
        return self._values[key]

    def __getattr__(self, name):
        return getattr(self._values, name)

因此,我可以直接在此类的对象上使用numpy方法,如shape,size,....我也可以执行obj.__add__(1)之类的操作,这会向obj._values添加1。但是,如果我尝试obj + 1,它会引发“不支持的操作数类型”。我希望obj + 1obj.__add__(1)的行为相同。这可以在不将__add__添加到Foo的情况下实现吗?

1 个答案:

答案 0 :(得分:0)

我可以看到你在这里尝试做什么,但它不会像你认为的那样工作。这是Python中非常明显的微妙之处。

你在想的是你所做的obj + 1 Python实际上正在调用obj.__add__(1)而且,在__add__找不到obj属性它将会失败到__getattr__

但这并不完全是算术运算符的工作方式,其实现实际上要复杂得多。在这种情况下,如果obj没有__add__方法,则会尝试调用右侧操作数的__radd__(用于“右侧添加”)方法来查看{{1}知道如何使用左手操作符添加。它不会让你得到例外。

还有其他涉及类型插槽的细微之处,我不会介入。

如果您希望自己的课程充当1的代理人,那么您有几个选择。这实际上取决于你实际想要完成什么,你可以考虑在一个单独的问题中提出。您可能只能直接子类 ndarray并在子类中实现其他功能。

如果您不想要ndarray的子类,您也可以考虑使用代理,例如来自wraptndarray。这可能是也可能不是你想要的。虽然你仍然可以继承ObjectProxy来覆盖你不想代理的方法,但它会使一个对象像走路,谈话,嘎嘎叫,甚至被称为ndarray

否则就会有繁琐的手动方法。