繁体   English   中英

子类化numpy.ndarray - 为什么__array_finalize__在这里没有被调用两次?

[英]Subclassing numpy.ndarray - why is __array_finalize__ not being called twice here?

根据引物上的子类ndarray ,所述__array_finalize__方法保证被调用,不管亚类是直接实例化,铸造作为视图或从模板创建。

特别是,显式调用构造函数时,称为方法的顺序是__new__ - > __array_finalize__ - > __init__

我有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

产生以下输出:

>>> 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'

如您所见, __array_finalize__作为行的结果被调用

 self = input_array.view(Frame)

问:为什么__array_finalize__不被再次调用的一部分__new__ - > __array_finalize__ - > __init__链?

在您链接到的文档,它描述了如何ndarray.__new__将调用__array_finalize__它构建阵列。 当你将实例创建为现有数组的view时,你的类的__new__方法会导致这种情况发生。 数组参数的view方法为你调用ndarray.__new__ ,并在实例返回给你之前调用你的__array_finalize__方法。

你没有看到__array_finalize__被调用两次,因为你没有第二次调用ndarray.__new__ 如果你的__new__方法除了view调用之外还包含对super().__new__的调用,你可能会看到__array_finalized__被调用两次。 这样的行为可能是错误的(或者至少比必要的慢),所以你不会这样做也就不足为奇了!

当调用重写子类的方法时,Python不会自动调用重写方法。 调用(或不调用)被覆盖的版本(直接使用super或,在本例中,通过另一个对象的view方法间接调用)取决于重写方法。

暂无
暂无

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

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