簡體   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