简体   繁体   English

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

[英]Writing a CSV file in Python with root.after gives an Error

Im programming a datalogger (programmed in Python 3.5.3) on a Raspberry Pi, where i write data coming in from an ADC into a CSV file. 我在Raspberry Pi上编程了一个数据记录器(用Python 3.5.3编程),在这里我将从ADC输入的数据写入CSV文件。 I also have a GUI (made with tkinter) where i want to control the beginning and the end of a measurement. 我也有一个GUI(用tkinter制作),我想在其中控制测量的开始和结束。 I start measuring by calling the following Function with a Pushbutton: 我通过使用按钮调用以下功能开始测量:

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)     

This works fine for the first 2048 repetitions, but after that i get the following error: 这对于前2048个重复工作正常,但是在此之后,我得到以下错误:

Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python3.5/tkinter/__init__.py", line 1562, in __call__
File "/usr/lib/python3.5/tkinter/__init__.py", line 608, in callit
File "/home/pi/Documents/loggerprojekt/gui.py", line 34, in do_start
OSError: [Errno 24] Too many open files

I dont get this Error when i write the data to the CSV file in an endless loop, but then i can't access the GUI to stop it. 在无休止的循环中将数据写入CSV文件时,我没有收到此错误,但是后来我无法访问GUI来停止它。 Is there a way i can avoid this Error using tkinter? 有没有办法我可以避免使用tkinter出现此错误?

It's impossible to reproduce your code, but my guess is that the "file" in the error message is not the csv file, but the file-like object that is being opened in the first line of do_start . 无法复制代码,但是我的猜测是错误消息中的“文件”不是csv文件,而是在do_start第一行中打开的类似文件的对象。 You do spi.open(0,0) , but you never call close on spi . 您执行spi.open(0,0) ,但从未在spi上调用close

I believe what happens is that even though after with open segment output.close() method is automatically called, it is the operating system which buffers the I/O calls and fails to close files as fast as your loop is opening them. 我相信会发生的事情是,即使在打开打开后自动调用了output.close()方法,还是由操作系统来缓冲I / O调用,并且无法像打开循环一样快地关闭文件。 This means that even after output.close(), OS still holds on the file a bit longer. 这意味着即使在output.close()之后,OS仍保留文件的时间更长。 There is similar issue discussed here . 有讨论类似的问题在这里

However this is difficult to test and verify. 但是,这很难测试和验证。 One method would be to call a sleep -function to let OS have time to do it's cleanup, but this would slow down the program quite a bit. 一种方法是调用sleep函数,以使OS有时间进行清理,但这会大大降低程序速度。 Also disabling buffering open(csvfilesave,"a", buffering=0) might help. 另外禁用打开缓冲(csvfilesave,“ a”,缓冲= 0)可能会有所帮助。 Slow I/O is more likely to cause problems on RPi and quite platform dependend. 缓慢的I / O更有可能在RPi和相当平台依赖上引起问题。

Anyhow, an easy fix for your problem would be to only open file once. 无论如何,解决您的问题的一个简单方法就是只打开一次文件。 Below is one example (I also removed recursion, because recursion because it will cause problems with big iterations): 下面是一个示例(我也删除了递归,因为递归,因为它会导致大的迭代问题):

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM