从Python中导入文件数据错误

时间:2013-08-12 02:34:51

标签: python

我在使用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

2 个答案:

答案 0 :(得分:5)

默认值data仅评估一次;最小实例的data属性引用相同的列表。

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

请参阅“Least Astonishment” in Python: The Mutable Default Argument

答案 1 :(得分: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已经为您的代码提供了正确的表单。我只是想解释一下这个理由。