使用root.after在Python中编写CSV文件会产生错误

时间:2018-02-23 10:11:42

标签: python csv tkinter raspberry-pi

我在Raspberry Pi上编程数据记录器(在Python 3.5.3中编程),在那里我将来自ADC的数据写入CSV文件。我还有一个GUI(用tkinter制作),我想控制测量的开始和结束。我通过按下按钮调用以下函数开始测量:

Repository

这适用于前2048次重复,但之后我收到以下错误:

def do_start():
  spi.open(0,0)
  ch0 = [0x0c,0x00,0x00]
  a = adc(ch0)
  b = a[1]
  b = b&0b00001111      
  c = a[2]

  value = c+256*b
  voltage = value/4096*5
  zeit = millis()
  voltage = round(voltage,2)
  data=[voltage,zeit]


  with open(csvfilesave,"a") as output:
                 writer = csv.writer(output, delimiter=",",lineterminator = '\n')
                 writer.writerow(data)
  root.after(100, do_start)     

当我在无限循环中将数据写入CSV文件时,我没有收到此错误,但是我无法访问GUI来停止它。有没有办法可以使用tkinter避免这个错误?

2 个答案:

答案 0 :(得分:3)

无法重现您的代码,但我的猜测是"文件"在错误消息中不是csv文件,而是在do_start的第一行中打开的类文件对象。您执行了spi.open(0,0),但从未在close上致电spi

答案 1 :(得分:0)

我相信发生的事情是,即使在开放段之后 output.close()方法被自动调用,它也是缓冲I / O的操作系统调用并且无法在循环打开文件时尽快关闭文件。这意味着即使在output.close()之后,OS仍然会在文件上保留更长时间。讨论过类似的问题here

然而,这很难测试和验证。一种方法是调用sleep -function让操作系统有时间进行清理,但这会使程序运行速度变慢。同时禁用缓冲 open(csvfilesave," a",buffering = 0)可能会有所帮助。缓慢的I / O更可能导致RPi和平台依赖的问题。

无论如何,对您的问题的一个简单的解决方法是只打开一次文件。下面是一个例子(我也删除了递归,因为递归因为它会导致大迭代的问题):

import csv

def do_start():
    with open(r"c:\temp\foobar.txt", "a") as output:
        for i in range(3000):  # replace this with custom looping logic
            append_to_file(output)

def append_to_file(open_file):
    writer = csv.writer(open_file, delimiter=",", lineterminator='\n')
    data = "My hovercraft", "full of eels"  # replace data with your voltage, zeit
    writer.writerow(data)

do_start()