简体   繁体   English

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

[英]python operators for numpy.ndarray like class

I have a class that has a numpy.ndarray as a member and behaves similar to ndarray by overloading __getitem__ and __getattr__ : 我有一个类,它有一个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)

Thus I can use the numpy method like shape, size, ... directly on an object of this class. 因此,我可以直接在这个类的对象上使用像shape,size,...这样的numpy方法。 I can also do things like obj.__add__(1) , which will add 1 to obj._values . 我也可以做像obj.__add__(1)这样的事情,它会给obj._values增加1。 However, if I try obj + 1 it raises "unsupported operand type(s)". 但是,如果我尝试obj + 1它会引发“不支持的操作数类型”。 I would like to get the same behaviour for obj + 1 as obj.__add__(1) . 我想为obj + 1obj.__add__(1)相同的行为。 Is this possible without adding __add__ to Foo ? 如果不向Foo添加__add__ ,这可能吗?

I can see what you're trying to do here, but it's not going to work the way you think it should. 我可以看到你在这里尝试做什么,但它不会像你认为的那样工作。 This is a very non-obvious subtlety in Python. 这是Python中非常明显的微妙之处。

What you're thinking is that what you do obj + 1 Python is actually calling obj.__add__(1) and that, failing to find an __add__ attribute on obj it will fall through to its __getattr__ . 你在想的是你做的obj + 1 Python实际上是在调用obj.__add__(1)而且,如果没有在obj上找到__add__属性,它将落到它的__getattr__

But this is not exactly how it works for arithmetic operators, the implementation of which is actually significantly more complicated. 但这并不完全适用于算术运算符,其实现实际上要复杂得多。 In this case if obj does not have an __add__ method, it will attempt to call the right-hand operand's __radd__ (for "right add") method to see if 1 knows how to add with the left-hand operator. 在这种情况下,如果obj没有__add__方法,它将尝试调用右侧操作数的__radd__ (用于“右侧添加”)方法,以查看1知道如何使用左侧操作符添加。 It does not so you get an exception. 它不会让你得到例外。

There are other subtleties involving type slots that I won't get into. 还有其他涉及类型插槽的细微之处,我不会介入。

If you want your class to act as a proxy for an ndarray you have a few options. 如果您希望您的课程充当ndarray的代理,您有几个选择。 It really depends on what you're actually trying to accomplish, which you might consider asking in a separate question. 这实际上取决于你实际想要完成什么,你可以考虑在一个单独的问题中提出。 You might just be able to subclass ndarray directly and implement your additional functionality in the subclass. 您可能只能直接子类化 ndarray并在子类中实现其他功能。

If you don't want a subclass of ndarray you might also consider using a proxy, such as the ObjectProxy from wrapt . 如果你不想要的子类ndarray您也可以考虑使用代理,如ObjectProxy缠住了 This may or may not be what you want. 这可能是也可能不是你想要的。 It will make an object that walks, talks, quacks like, and is even named ndarray , though you can still subclass ObjectProxy to override methods that you don't want proxied. 虽然你仍然可以ndarray ObjectProxy以覆盖你不想要代理的方法,但它会使一个对象像走路,谈话, ndarray ,甚至命名为ndarray

Otherwise there's the tedious manual method. 否则就会有繁琐的手动方法。

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

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