2017-12-29 76 views
0

私はGitHubでhereを見つけたcsvパースにjsonを調整しようとしています。コードが定義された3つの引数で、端末から実行するように設定されている:モジュールの問題がargsに沿って渡される

を作成する ノード、JSONファイルへ パス、CSVファイルへ パス、私は別のpythonから実行するためにそれを呼び出すことができるように私が変更されたコードにしようとしています私が書いているスクリプト。私はターミナルから実行するモジュールについて学んだから、彼らはif __name__ == "__main__":を使用しますが、別のPythonスクリプトから実行したい場合は、def main()のような定義を作成する必要があります。

Traceback (most recent call last): 
    File "/Users/Documents/Projects/test.py", line 8, in <module> 
    jsontocsv2.main('cars', SourceFile, filename) 
    File "/Users/Documents/Projects/jsontocsv2.py", line 84, in main 
    reduce_item(node, item) 
    File "/Users/Documents/Projects/jsontocsv2.py", line 57, in reduce_item 
    reduce_item(key + '_' + to_string(sub_key), value[sub_key]) 
    File "/Users/Documents/Projects/jsontocsv2.py", line 61, in reduce_item 
    reduced_item[to_string(key)] = to_string(value) 
NameError: name 'reduced_item' is not defined 

誰でもにポイントを助けることができる:ここで

import jsontocsv2 
import json 

filename = 'test2.csv' 

SourceFile = 'carapi.json' 

jsontocsv2.main('cars', SourceFile, filename) 

は私が取得していたエラーは以下のとおりです。ここで

import sys 
import json 
import csv 

# https://github.com/vinay20045/json-to-csv 
## 
# Convert to string keeping encoding in mind... 
## 


def to_string(s): 
    try: 
     return str(s) 
    except: 
     # Change the encoding type if needed 
     return s.encode('utf-8') 

def reduce_item(key, value): 
    global reduced_item 

    # Reduction Condition 1 
    if type(value) is list: 
     i = 0 
     for sub_item in value: 
      reduce_item(key + '_' + to_string(i), sub_item) 
      i = i + 1 

    # Reduction Condition 2 
    elif type(value) is dict: 
     sub_keys = value.keys() 
     for sub_key in sub_keys: 
      reduce_item(key + '_' + to_string(sub_key), value[sub_key]) 

    # Base Condition 
    else: 
     reduced_item[to_string(key)] = to_string(value) 

# the module I created and moved the contents of __main__ to here 
def main(node, json_file_path, csv_file_path): 
    # Reading arguments 
    # node = sys.argv[1] 
    # json_file_path = sys.argv[2] 
    # csv_file_path = sys.argv[3] 

    fp = open(json_file_path, 'r') 
    json_value = fp.read() 
    raw_data = json.loads(json_value) 
    print(raw_data['tag']) 

    try: 
     data_to_be_processed = raw_data[node] 
    except: 
     data_to_be_processed = raw_data 

    processed_data = [] 
    header = [] 
    for item in data_to_be_processed: 
     reduced_item = {} 
     reduce_item(node, item) 

     header += reduced_item.keys() 

     processed_data.append(reduced_item) 

    header = list(set(header)) 
    header.sort() 

    with open(csv_file_path, 'a') as f: 
     writer = csv.DictWriter(f, header, quoting=csv.QUOTE_ALL) 
     writer.writeheader() 
     for row in processed_data: 
      writer.writerow(row) 

    print ("Just completed writing csv file with %d columns" % len(header)) 


# if __name__ == "__main__": 
#  if len(sys.argv) != 4: 
#   print ("\nUsage: python json_to_csv.py <node_name> <json_in_file_path> <csv_out_file_path>\n") 
#  else: 
#   # Reading arguments 
#  main(sys.argv) 

は、私がjsontocsv2.py呼び出すために使用しています他のPythonスクリプトですこれを修正する方法の正しい方向は?私はスタックのオーバーフローで多くの検索を行い、同様の問題を持つ記事を見つけましたが、これをどのように動作させるのか把握できませんでした。

+4

「グローバル」として定義するのは一般的には良い考えではありません。代わりに 'reduce_item = reduce_item(node、item、reduced_item)'を使って 'main()'から関数定義を 'def reduce_item(key、value、reduced_item):'に変更し、 'main()'から呼び出してください。 'reduce_item(node、item)'のうちのどれか。ここを通過するコードがかなりあるので、それだけで動作するかどうかはわかりません。 – roganjosh

+0

私の提案はうまくいきますか?私はむしろあなたのjsonで推測せず、最初から自分自身でテストを構築しようとしますが、私の提案がどこに届いたかに関するフィードバックはありません。 – roganjosh

+1

おそらく 'Namerror'の問題とは関係ありませんが、GitHubのページには、バージョン3を使用している場合、(他の)問題につながるjson_to_csv.pyがPython 2.7用に書かれていると書かれています。 – martineau

答えて

0

私が望むように機能するコードを手に入れることができました。

global reduced_item()文をdef reduced_item()機能から私が作成したdef main(node, json_file_path, csv_file_path)機能に移動するだけでした。そのグローバル変数が定義していないと述べると、なぜこれが機能するのか分かりません。

また、何かを定義するのはなぜ一般的にいい考えではないのですか?Global皆さんにこれをもっと良くするための推奨事項がある場合は、私は指導のためにオープンしています。お手伝いをしていただきありがとうございます。

+0

' global reduced_item'ステートメントを動かす理由は、なぜなら 'reduced_item'は、' main() '関数のローカル変数ではなく、モジュールレベルの「グローバル」変数であるためです。これにより、他の関数である 'reduce_item()'のその名前への参照を(関数内で 'global'として宣言しているかどうかにかかわらず)正しく解決されるようになりました。これは、Pythonが名前を解決する方法によるものです。これは、Pythonのスコープ規則の仕組みの良い説明のために、別の質問に答えています(https://stackoverflow.com/a/292502/355230)。 – martineau

関連する問題