Python中奇怪的类初始化

时间:2017-01-13 08:03:30

标签: python python-3.x oop numpy

在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数组,不是一种循环调用(应该崩溃)?

2 个答案:

答案 0 :(得分:1)

Foobar.dtype是一个类属性。

这是一个附加到类定义而不是类的单个实例的变量。如果您熟悉其他流行的面向对象语言,这个概念非常类似于Java和C#中的静态变量。

Python文档,更详细地解释了https://docs.python.org/3/tutorial/classes.html#class-objects

在您提供的示例中考虑了Foobar类:

Foobar是一个类

myFoobarFoobar

的一个实例

让我们假装还有另一个例子:yourFoobar

然后myFoobaryourFoobar(和任何其他实例)可能需要能够访问某些数据(在本例中是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数组所需的类型Foobarmodel)。它是一个类属性,而不是全局属性,因此它由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'添加值。