tim*_*geb 5 python inheritance numpy
根据这个subclassing 入门,无论子类是直接实例化、转换为视图还是从模板创建,都可以保证调用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
Run Code Online (Sandbox Code Playgroud)
产生以下输出:
>>> 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'
Run Code Online (Sandbox Code Playgroud)
如您所见,__array_finalize__由于该行而被调用
self = input_array.view(Frame)
Run Code Online (Sandbox Code Playgroud)
问题:为什么__array_finalize__不再作为__new__-> __array_finalize__->__init__链的一部分被调用?
在您链接到的文档中,它描述了如何ndarray.__new__调用__array_finalize__它构造的数组。__new__当您将实例创建为view现有数组时,您的类的方法会导致这种情况发生。view数组参数上的方法正在为您调用,ndarray.__new__并且它会__array_finalize__在实例返回给您之前调用您的方法。
您不会看到__array_finalize__被呼叫两次,因为您不会ndarray.__new__第二次呼叫。如果您的方法除了调用之外还__new__包含调用,您可能会看到调用两次。这种行为可能会有错误(或者至少比必要的慢),所以你不这样做也就不足为奇了!super().__new__view__array_finalized__
当重写子类的方法被调用时,Python 不会自动调用重写的方法。由重写方法来调用(或不调用)重写版本(直接使用super或在本例中通过另一个对象的view方法间接调用)。
| 归档时间: |
|
| 查看次数: |
1051 次 |
| 最近记录: |