假设我有一个简单的Test类继承自numpy.ndarray(子类化的文档ndarray).该类创建一个对象,该对象是另一个对象的局部视图ndarray.现在我想创建一个就地修改这个视图的方法.就像是:
import numpy
class Test(numpy.ndarray):
def __new__(cls, info='Test class'):
base = numpy.ndarray.__new__(cls, (6, 2), dtype=float)
view = base[0:2, :]
view.info = info
return view
def __array_finalize__(self, obj):
if obj is None:
return
self.info = getattr(obj, 'info', None)
def change_view(self, start, stop):
"""This is the method I'd like to implement"""
# Incorrect, but represents what I am looking for
self = self.base[start:stop]
if __name__ == '__main__':
t = Test()
print(t)
print(t.info)
t.change_view(1, 5)
print(t)
print(t.info)
Run Code Online (Sandbox Code Playgroud)
我希望该方法.change_view(x)修改.base属性的视图以显示行[1:5]而不是[0:2]默认情况下的行__new__().
这可能吗?如果是这样,怎么样?否则,为什么不呢?请注意,.base永远不会更改(它总是占用相同的内存空间),我只想更改它的视图.
change_view().我知道这self = self.base[start:stop]是不正确的,我知道并理解为什么,但我认为这是一个代表我正在寻找的东西的简短方法.self[:] = ...或self.data = ....但是,在更改视图大小时这将不起作用(情况确实如此).这里已经提出了这个问题(或者至少它是一个类似的情况),但是答案提到了返回修改后的数组的解决方案(即没有就地修改)或者使用了包装器对象(即具有数组的属性)待修改).
我知道这些可能性,我知道它们可以更简单甚至更方便.但是,我想了解为什么(如果是这样的话)不可能做我想要的.
1)您无法就地更改 ndarray 实例或子类实例指向的数据。对不起!事实证明,可以就地更改 ndarray 实例指向的数据,但这是一个糟糕的主意,希望很快就会被删除:-)。请参阅https://github.com/numpy/numpy/issues/7093
2)你尝试这样分配self只会改变self方法本地绑定内变量的绑定,我担心这表明对Python的执行和对象模型如何工作存在相当基本的误解。我之所以提出这个问题,是因为成功的子类化ndarray很困难。真的很难。几乎不可能。pandas(例如,流行库的开发人员放弃了。)尽管该文档给出了误导性的印象,但 numpy 并不是真正设计来支持子类化的,而且它的工作效果也不是很好。我通常建议没有人尝试子类化ndarray;如果你还不是一名专业的 Python 程序员,那么这个数字会增加十倍。也许我们会删除那个愚蠢的页面并完全禁用子类化,除非它会破坏向后兼容性:-(。我建议找到一种不同的策略来解决您的问题。
| 归档时间: |
|
| 查看次数: |
303 次 |
| 最近记录: |