[英]Subclassing numpy.ndarray - why is __array_finalize__ not being called twice here?
According to this primer on subclassing ndarray
, the __array_finalize__
method is guaranteed to be called, no matter if the subclass is instantiated directly, casted as a view or created from a template. 根据此引物上的子类
ndarray
,所述__array_finalize__
方法保证被调用,不管亚类是直接实例化,铸造作为视图或从模板创建。
In particular, when calling the constructor explicitly, the order of methods called is __new__
-> __array_finalize__
-> __init__
. 特别是,显式调用构造函数时,称为方法的顺序是
__new__
- > __array_finalize__
- > __init__
。
I have the following simple subclass of ndarray
which allows an additional title
attribute. 我有
ndarray
的以下简单子类,它允许一个额外的title
属性。
class Frame(np.ndarray):
def __new__(cls, input_array, title='unnamed'):
print 'calling Frame.__new__ with title {}'.format(title)
self = input_array.view(Frame) # does not call __new__ or __init__
print 'creation of self done, setting self.title...'
self.title = title
return self
def __array_finalize__(self, viewed):
# if viewed is None, the Frame instance is being created by an explicit
# call to the constructor, hence Frame.__new__ has been called and the
# title attribute is already set
#
# if viewed is not None, the frame is either being created by view
# casting or from template, in which case the title of the viewed object
# needs to be forwarded to the new instance
print '''calling Frame.__array_finalize__ with type(self) == {} and
type(viewed) == {}'''.format(type(self), type(viewed))
if viewed is not None:
self.title = getattr(viewed, 'title', 'unnamed')
print self.title
which produces the following output: 产生以下输出:
>>> f = Frame(np.arange(3), 'hallo')
calling Frame.__new__ with title hallo
calling Frame.__array_finalize__ with type(self) == <class '__main__.Frame'> and
type(viewed) == <type 'numpy.ndarray'>
unnamed
creation of self done, setting self.title...
>>> f.title
'hallo'
As you can see, __array_finalize__
is being called as a result of the line 如您所见,
__array_finalize__
作为行的结果被调用
self = input_array.view(Frame)
Question: why is __array_finalize__
not being called again as part of the __new__
-> __array_finalize__
-> __init__
chain? 问:为什么
__array_finalize__
不被再次调用的一部分__new__
- > __array_finalize__
- > __init__
链?
In the documentation you link to, it describes how ndarray.__new__
will call __array_finalize__
on the arrays it constructs. 在您链接到的文档,它描述了如何
ndarray.__new__
将调用__array_finalize__
它构建阵列。 And your class's __new__
method is causing that to happen when you create your instance as a view
of an existing array. 当你将实例创建为现有数组的
view
时,你的类的__new__
方法会导致这种情况发生。 The view
method on the array argument is calling ndarray.__new__
for you, and it calls your __array_finalize__
method before the instance is returned to you. 数组参数的
view
方法为你调用ndarray.__new__
,并在实例返回给你之前调用你的__array_finalize__
方法。
You don't see __array_finalize__
called twice because you're not calling ndarray.__new__
a second time. 你没有看到
__array_finalize__
被调用两次,因为你没有第二次调用ndarray.__new__
。 If your __new__
method included a call to super().__new__
in addition to the view
call, you probably would see __array_finalized__
called twice. 如果你的
__new__
方法除了view
调用之外还包含对super().__new__
的调用,你可能会看到__array_finalized__
被调用两次。 Such behavior would probably be buggy (or at least, slower than necessary), so it's no surprise you're not doing it! 这样的行为可能是错误的(或者至少比必要的慢),所以你不会这样做也就不足为奇了!
Python doesn't automatically call overridden methods when the overriding subclass's method gets called. 当调用重写子类的方法时,Python不会自动调用重写方法。 It's up to the overriding method to call (or not call) the overridden version (directly with
super
or, as in this case, indirectly via another object's view
method). 调用(或不调用)被覆盖的版本(直接使用
super
或,在本例中,通过另一个对象的view
方法间接调用)取决于重写方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.