在python库pytides中,我遇到了一种奇怪的方法来初始化一个类(Tide类及其initialization )。 我在下面复制了代码的简化版本:
import numpy as np
class Foo(object):
def __init__(self,x,y):
self.x = x
self.y = y
class Foobar(object):
dtype = np.dtype([('fooObj', object),
('A', float),
('B', float)])
def __init__(self,model):
'''model: an ndarray of type Foobar.dtype '''
self.model = model
# initialize a Foobar object
myFoos = [Foo(4,3),Foo(4,9),Foo(0,2)]
A = [2,3,4]
B = [8,9,0]
model = np.zeros(len(myFoos), dtype = Foobar.dtype)
model['fooObj'] = myFoos #what is that?!?
model['A'] = A
model['B'] = B
myFoobar = Foobar(model=model)
据我所知,Foobar中的dtype变量是一个全局变量,但我不明白它有什么意义。是否只是提供一种初始化Foobar的便捷方式?此外,Foobar类在构造时需要一个Foobar.dtype数组,不是一种循环调用(应该崩溃)?
答案 0 :(得分:1)
Foobar.dtype
是一个类属性。
这是一个附加到类定义而不是类的单个实例的变量。如果您熟悉其他流行的面向对象语言,这个概念非常类似于Java和C#中的静态变量。
Python文档,更详细地解释了https://docs.python.org/3/tutorial/classes.html#class-objects
在您提供的示例中考虑了Foobar类:
Foobar
是一个类
myFoobar
是Foobar
让我们假装还有另一个例子:yourFoobar
然后myFoobar
和yourFoobar
(和任何其他实例)可能需要能够访问某些数据(在本例中是numpy
数据类型的定义),这是同样适用于Foobar
的所有实例。因此,有一个论点,它应该与类相关联,而不是与每个单独的实例相关联。 (但也有一些论点认为类属性/静态变量弊大于利:Why are static variables considered evil?)
即。避免在你为Foobar的每个实例分配它自己的同一个numpy dtype定义的实例的地方写一个方法,比如......
class Foobar(object):
def __init__(self,model):
'''model: an ndarray of type self.dtype '''
self.model = model
self.dtype = np.dtype([('fooObj', object),
('A', float),
('B', float)])
答案 1 :(得分:1)
这个初始化没有太多奇怪的地方,dtype
保存了它在初始化期间收到的numpy数组所需的类型Foobar
(model
)。它是一个类属性,而不是全局属性,因此它由Foobar
类的所有实例共享。
初始化model
的方式可能看起来很奇怪,但它只是根据指定字段的名称初始化model
,这可能最好通过在其间打印出model
来证明步骤:
model['fooObj'] = myFoos
print(model)
array([(<__main__.Foo object at 0x7f125ed93828>, 0.0, 0.0),
(<__main__.Foo object at 0x7f125ed93940>, 0.0, 0.0),
(<__main__.Foo object at 0x7f125ed93240>, 0.0, 0.0)],
dtype=[('fooObj', 'O'), ('A', '<f8'), ('B', '<f8')])
添加'fooObj'
对象类型的值。虽然:
model['A'] = A
model['B'] = B
分别为float
类型'A'
和'B'
添加值。