open()后关闭文件不起作用

时间:2016-03-28 05:09:18

标签: python

当我运行此函数时,它会挂起,因为我使用open()函数来读取csv,我需要关闭它。我将close()函数放在我认为应该去的地方,但它似乎并没有起作用。我已经将close()函数与"一致,而True"缩进,"对于i in byte"缩进,它也不起作用。我做错了什么?

def parse(text):
    #states
    is_token = False
    previous_character_is_escape = False
    no_quote_value = True
    quote_value = False


    file_base = os.path.basename('"app/csv_upload_directory/%s' % text)
    new_base = os.path.splitext(file_base)[0]

    row_counter = 1
    token_counter = 0
    fo = open("csv_upload_directory/%s_results.csv" % new_base, "w+")

    fo.write("Row %i" % row_counter + '\n')
    row_counter += 1
    with io.open(text,'rb',newline=None) as f:
        while True:
            byte = f.read(1)
            for i in byte:
                #print "%s,%s" % (no_quote_value,previous_character_is_escape)
                if is_token == False:
                    if i == '"':
                        fo.write(i)
                        token_counter = 0
                        is_token = True
                        no_quote_value = False
                        quote_value = True
                    elif i == '\n':
                        fo.write(",")
                        fo.write("%i" % token_counter)
                        fo.write('\n')
                        fo.write("Row %i" % (row_counter))
                        fo.write("\n")
                        token_counter = 0
                        row_counter += 1
                    elif i == ',':
                        fo.write(",")
                        fo.write("%i" % token_counter)
                        fo.write('\n')
                        token_counter = 0
                    elif no_quote_value == True:
                        fo.write(i)
                        token_counter += 1
                        is_token = True
                        quote_value = False
                    else:
                        fo.write(i)
                        token_counter += 1


                elif is_token == True:
                    # start of an escape sequence
                    if i == '\\':
                        fo.write(i)
                        token_counter += 1
                        previous_character_is_escape = True
                    # for line delimiter, the quoted values are being processed outside token
                    elif no_quote_value == True and i == '\n':
                        fo.write(",")
                        fo.write("%i" % token_counter)
                        fo.write('\n')
                        fo.write("Row %i" % (row_counter))
                        fo.write("\n")
                        token_counter = 0
                        row_counter += 1
                        is_token = False
                    # if token is not a quoted value but ends with quotes, and there is no escape character
                    elif no_quote_value == True and previous_character_is_escape == False and i == '"':
                        fo.write(i)
                        fo.write("This is a not a valid token, this is not a quoted value but there is an ending quote")
                        return False
                    # builds off previous_character_is_escape and captures any escape sequence
                    elif previous_character_is_escape == True:
                        fo.write(i)
                        token_counter += 1
                        previous_character_is_escape = False
                    # this type of quote is the end of token, returns back to other if statement
                    elif previous_character_is_escape == False and i == '"':
                        fo.write(i)
                        no_quote_value = True
                        quote_value = False
                        is_token = False
                    # if token starts as a quote but ends without quotes
                    elif quote_value == True and previous_character_is_escape == False and i == ',':
                        fo.write(i)
                        fo.write("This is not a valid token, there should be a quote at the end of this token")
                        return False
                    # this comma marks the end of a non quoted token, this invokes a newline
                    elif no_quote_value == True and previous_character_is_escape == False and i == ',':
                        fo.write(",")
                        fo.write("%i" % token_counter)
                        fo.write('\n')
                        token_counter = 0
                        is_token = False
                    elif no_quote_value == False and i == ',':
                        fo.write(i)
                        fo.write("DONG")
                    else:
                        fo.write(i)
                        token_counter += 1
        fo.close()

parse('example.csv')

2 个答案:

答案 0 :(得分:1)

从您的评论中,听起来关闭文件实际上并不是您的问题(尽管这是您应该注意的事情)。真正的问题是你的功能永远不会结束。

这是因为您永远循环,尝试每次迭代读取一个字符。当文件全部被读取后,您没有注意到它从f.read(1)获得了空字节串。你应该添加一些逻辑来突破循环。

另一个问题:您目前正在使用for循环来迭代您从read(1)获得的单字节字符串。没有必要使用该循环,并且很难使用while语句突破break循环。

尝试:

with io.open(text,'rb',newline=None) as f, fo:   # add fo to the with statement
    while True:
        i = f.read(1)        # read directly to "i", no need for the extra loop on bytes
        if i == '':          # check if read gave us an empty string (happens at EOF)
            break
        if is_token == True:
            # ...

答案 1 :(得分:0)

所以,你在这里打开两个文件。一个引用fo,另一个引用f

对于fo,您使用open()方法执行文件操作,您需要使用fo.close()正确关闭它。

然而,f并非如此。由于您使用的是 with ... open()方法,因此无需关闭它,因为它在完成代码块执行后有效地处理关闭文件。阅读相关文档here

相关问题