2

我在 Python 中从文件中导入数据时遇到了一些问题。我对 Python 很陌生,所以我的错误可能很简单。

我正在阅读 3 列、制表符分隔的没有标题的文本文件。我正在使用三个不同的数据文件创建数据文件的 3 个实例。

我可以看到每个对象都引用了不同的内存位置,所以它们是分开的。

当我查看存储在每个实例中的数据时,每个实例都有相同的内容,由三个相互附加的数据文件组成。

我做错了什么?

要读入数据的类是:

class Minimal:

    def __init__(self, data=[]):
        self.data = data

    def readFile(self, filename):
        f = open(filename, 'r')

        for line in f:
            line = line.strip()
            columns = line.split()
            #creates a list of angle, intensity and error and appends it to the diffraction pattern
            self.data.append( [float(columns[0]), float(columns[1]), float(columns[2])] )
        f.close()

    def printData(self):
        for dataPoint in self.data:
            print str(dataPoint)

数据文件如下所示:

1   4   2
2   5   2.3
3   4   2
4   6   2.5
5   8   5
6   10  3

我用来实际创建 Minimal 实例的程序是:

from minimal import Minimal

d1 = Minimal()
d1.readFile("data1.xye")

d2 = Minimal()
d2.readFile("data2.xye")

d3 = Minimal()
d3.readFile("data3.xye")


print "Data1"
print d1
d1.printData()

print "\nData2"
print d2
d2.printData()

print "\nData3"
print d3
d3.printData()

输出是:

Data1
<minimal.Minimal instance at 0x016A35F8>
[1.0, 4.0, 2.0]
[2.0, 5.0, 2.3]
[3.0, 4.0, 2.0]
[4.0, 6.0, 2.5]
[5.0, 8.0, 5.0]
[6.0, 10.0, 3.0]
[2.0, 4.0, 2.0]
[3.0, 5.0, 2.3]
[4.0, 4.0, 2.0]
[5.0, 6.0, 2.5]
[6.0, 8.0, 5.0]
[7.0, 10.0, 3.0]
[3.0, 4.0, 2.0]
[4.0, 5.0, 2.3]
[5.0, 4.0, 2.0]
[6.0, 6.0, 2.5]
[7.0, 8.0, 5.0]
[8.0, 10.0, 3.0]

Data2
<minimal.Minimal instance at 0x016A3620>
[1.0, 4.0, 2.0]
[2.0, 5.0, 2.3]
[3.0, 4.0, 2.0]
[4.0, 6.0, 2.5]
[5.0, 8.0, 5.0]
[6.0, 10.0, 3.0]
[2.0, 4.0, 2.0]
[3.0, 5.0, 2.3]
[4.0, 4.0, 2.0]
[5.0, 6.0, 2.5]
[6.0, 8.0, 5.0]
[7.0, 10.0, 3.0]
[3.0, 4.0, 2.0]
[4.0, 5.0, 2.3]
[5.0, 4.0, 2.0]
[6.0, 6.0, 2.5]
[7.0, 8.0, 5.0]
[8.0, 10.0, 3.0]

Data3
<minimal.Minimal instance at 0x016A3648>
[1.0, 4.0, 2.0]
[2.0, 5.0, 2.3]
[3.0, 4.0, 2.0]
[4.0, 6.0, 2.5]
[5.0, 8.0, 5.0]
[6.0, 10.0, 3.0]
[2.0, 4.0, 2.0]
[3.0, 5.0, 2.3]
[4.0, 4.0, 2.0]
[5.0, 6.0, 2.5]
[6.0, 8.0, 5.0]
[7.0, 10.0, 3.0]
[3.0, 4.0, 2.0]
[4.0, 5.0, 2.3]
[5.0, 4.0, 2.0]
[6.0, 6.0, 2.5]
[7.0, 8.0, 5.0]
[8.0, 10.0, 3.0]

Tool completed successfully
4

2 回答 2

5

默认值data只计算一次;dataMinimal 实例的属性引用相同的列表。

>>> class Minimal:
...     def __init__(self, data=[]):
...         self.data = data
... 
>>> a1 = Minimal()
>>> a2 = Minimal()
>>> a1.data is a2.data
True

替换如下:

>>> class Minimal:
...     def __init__(self, data=None):
...         self.data = data or []
... 
>>> a1 = Minimal()
>>> a2 = Minimal()
>>> a1.data is a2.data
False

请参阅Python 中的“Least Astonishment”:可变默认参数

于 2013-08-12T02:39:00.470 回答
1

考虑以下:

def d():
   print("d() invoked")
   return 1

def f(p=d())
   pass

print"("Start")
f()
f()

它打印

d() invoked
Start

不是

Start
d() invoked
d() invoked

为什么?因为默认参数是根据函数定义计算的(并存储在某种内部全局变量中,以便以后每次需要它们时重用)。它们不是在每次函数调用时计算的。

换句话说,它们的行为或多或少类似于:

_f_p_default= d()
def f(p)
   if p is None: p= _f_p_default
   pass

在您的代码中进行上述替换,您将立即理解问题所在。

@falsetru 已经为您的代码提供了正确的格式。我只是想解释理由。

于 2013-08-12T03:13:28.573 回答