2017-05-15 14 views
2

私はCSVを受け取り処理します。私はCSVファイルの行を数えて、最後まで確実に行おうとしています。UnboundLocalError:割り当て前にローカル変数 'document'が参照されています

def parse_campaigns_cutsheet(country_code, input_file, DB, DB_hist, zip_id): 

    filecontent = urllib2.urlopen(input_file) 
    count = 0 

    csvFile = csv.DictReader(filecontent) 
    rowage = len(list(csvFile)) 

    for row in csvFile: 
     count += 1 

     if 'MM' not in row['Tier']: 
      continue 

     if RB_COUNTRIES_new[country_code]['cut_sheet_country'] != row['Country']: 
      continue 

     document = DB.find_one({'rb_account_id': RB_COUNTRIES_new[country_code]['rb_account_id']}) 

     if document is None: 
      continue 

     DB.save(document) 

report_work(document, DB, DB_hist) 

次のエラーUnboundLocalError: local variable 'document' referenced before assignmentが引き続き発生します。もし私がrowage = len(list(csvFile))行を削除すればうまく動作しますか?

+0

'csvFile'はジェネレータですが、' list(csvFile) 'によってジェネレータが使い果たされました。したがって、行 'rowage = len(list(csvFile))'が存在する場合、forループは入力されません。 forループが入力されない場合、 'document'は定義されません。したがって、あなたのエラー – user2829759

答えて

3

これは、DictReaderがジェネレータであるために発生します。

DictReaderに電話すると、すべての値がリストに追加され、それ以上の繰り返しはありません。

forループが繰り返し処理しようとすると、決して実行されず、documentは決して割り当てられません。

あなたが何をしようとして達成したい場合は、リストへの参照を保持し、その後、リストを反復処理することができます。

... 
csvFile = csv.DictReader(filecontent) 
filecontent_list = list(csvFile) 
rowage = len(filecontent_list) 

for row in filecontent_list: 
... 

念頭してください - これは平均でありますあなたのすべてのデータはメモリに保存されます! 強制的にリストにすることなくジェネレータを反復処理するときは、毎回1回の反復だけがメモリに保存されます。

+0

* "これは' DictReader'がジェネレータであるために発生します。 "*ジェネレータはワンショットイテラブルなので、データを一度だけ繰り返し処理できます。次に繰り返し処理すると、 StopIteration'例外です。イテレーターの中には独自のイテレーターがあるものもあります。 * "DictReaderでリストを呼び出すと、リストにすべての値が返され、それ以上は反復できなくなります。" * 'DictReader'は、データの反復処理を行った後もまだiterableとみなされますが、反復後に反復可能です。 – direprobs

関連する問題