2016-03-28 8 views
0

この関数を実行すると、open()関数を使用してcsvを読み込んでいるため、関数を終了する必要があります。私はclose()関数を置くと思いますが、動作していないようです。私はclose()関数を "while True"インデント、 "for i in byte"インデントに合わせて置いていますが、どちらも機能しません。私は間違って何をしていますか?open()の後のファイルを閉じる

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') 
+0

あなたがキャッチするように 'try..except'ブロック(https://docs.python.org/2/tutorial/errors.html)内のコードの関連部分をラップ例外。 Exceptionのタイプは、一般に、何が間違っているかの手がかりを与えます。 –

+0

@AlexReynolds:解析関数は意図したとおりに動作していますが、現在はcsvの最後に到達していますが、手動でコンソールからエスケープしない限り、そこに待機します。 – Paul

+0

'with'文がそれを処理するので、' f.close() 'は必要ありません(' with'が終了すると、自動的に塗りつぶされます)。同じ 'with'文(またはネストされた文)に' fo'を含めるべきでしょう。それ以外に、私が見る唯一の問題は、エラーがなければコードが永遠に実行されることです。すべての文字を読み終えたら、 'while True'ループから抜け出すロジックを追加する必要があります。 – Blckknght

答えて

1

あなたのコメントから、ファイルを閉じるのは実際には問題ではないと思われます(あなたの面倒を見るべきではありますが)。本当の問題は、あなたの関数が決して終わらないということです。

これは、反復ごとに1文字を読み込もうとすると永遠にループしているからです。ファイルがすべて読み込まれると、あなたは空のバイト列をf.read(1)から得ることに気付かないでしょう。ループが発生すると、ループから脱出するためにいくつかのロジックを追加する必要があります。

さらなる問題:現在、read(1)から取得している1バイト文字列に対して、forループを繰り返し使用しています。そのループは必要ありません。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: 
      # ... 
0

ここでは2つのファイルを開きます。 1つはfo、もう1つはfです。

foの場合は、メソッドを使用してファイル操作を行い、fo.close()で適切に終了する必要があります。

ただし、これはfの場合ではありません。 with... open()メソッドを使用しているため、コードブロックの実行が完了した後にファイルを効率的に処理するため、コードを閉じる必要はありません。関連文書hereについて読む。