2017-03-21 12 views
0

私は自分のプログラムでさまざまな機能を分けて、物事を整理しようとしています。そして、あるモジュールで作成された変数を別のモジュールで使用しようとしています。私はglobal list_of_namesを使ってみましたが、うまくいきませんでした。とにかくそうしないことをお勧めします。モジュール間で変数を使用する最も良い方法は? (Python3)

以下は私のコードのサンプルです。私の意見では、list_of_namesを関数の引数として渡すのは意味がありません。なぜなら、渡すべき実際の引数を除いて、これを行う必要がある他の複数の変数があるからです。

残念ながら、私がread_jsonをengine.pyに移動しても、私は同じように問題を起こしていました。また、list_of_namesも参照する必要があります。

# main.py: 
import json 
from engine import create_person 
def read_json(): 
    with open('names.json', 'r') as file 
     data = json.load(file) 
    return data 
list_of_names = read_json() 
person1 = create_person() 

# engine.py: 
from random import choice 
def create_person(): 
    name = choice(list_of_names) 
    new_person = { 
     'name': name, 
     # other keys/values created in similar fashion 
    } 
    return new_person 

EDIT1: ここに私の新しいコードです。私にとって、これはパラメータリストを作成して関数内で分解するのは効率的ではないようです。 (私はこの例では変数名を再利用していることを知っています)次に、これらのパラメータのいくつかを他の関数に渡す必要があります。一般的に

# main.py: 
import json 
from engine import create_person 
def read_json(): 
    with open('names.json', 'r') as file 
     data = json.load(file) 
    return data 

player_id_index = 0 
list_of_names = read_json() 
person_parameters = [ 
    list_of_names, 
    dict_of_locations, 
    player_id_index, 
    dict_of_occupations, 
    . 
    . 
    . 
] 

person1, player_id_index = create_person() 

# engine.py: 
from random import choice 
def create_person(person_params): 
    list_of_names = person_params[0] 
    dict_of_locations = person_params[1] 
    player_id_index = person_params[2] 
    dict_of_occupations = person_params[3] 
    . 
    . 
    . 
    attr = person_params[n] 

    name = choice(list_of_names) 
    location = get_location(dict_of_locations) # a function elsewhere in engine.py 
    p_id = player_id_index 
    occupation = get_occupation(dict_of_occupations) # a function elsewhere in engine.py 

    new_person = { 
     'name': name, 
     'hometown': location, 
     'player id': p_id, 
     'occupation': occupation, 
     . 
     . 
     . 
    } 

    player_id_index += 1 
    return new_person, player_id_index 
+5

複数のモジュール間で同じ変数を使用しないでください。ほとんどの場合、同じ変数を複数の関数に渡って使用しないでください。関数の引数と戻り値は、ほとんどの場合、関数間でデータを渡す正しい方法です。 – user2357112

+0

上記で要約すると、あなたのコードにはいくつかのOOP(Object Oriented Programming)構造がありますか?コードを読みやすく、メンテナンス性と再利用性が向上します。 – 0xDEFACED

+0

@StevenRumbalski @ user2357112 'create_person(mylist)'のような意味ですか?私が述べたように、このように関数に多くの引数を渡さなければならないので、実用的ではありません。 – drewd423

答えて

2

あなたは、共有グローバルな状態に頼るべきではありません。状態を共有する必要がある場合は、オブジェクトの状態をカプセル化するか、関数の引数として渡します。

特定の問題については、一連のオプションからランダム辞書をアセンブルしたいようです。それが対象となる場合がありますように{'armor': 'naked', 'weapon': 'bow', 'health': 15, 'name': 'steve'}のような辞書が見えること

>>> for _ in range(4): 
...  print(create_person(person_options)) 
... 
{'armor': 'naked', 'weapon': 'bow', 'health': 15, 'name': 'steve'} 
{'armor': 'iron', 'weapon': 'sword', 'health': 8, 'name': 'fred'} 
{'armor': 'iron', 'weapon': 'sword', 'health': 6, 'name': 'john'} 
{'armor': 'iron', 'weapon': 'sword', 'health': 12, 'name': 'john'} 

注:アクションで

from random import choice 

person_options = { 
    'name': ['fred', 'mary', 'john', 'sarah', 'abigail', 'steve'], 
    'health': [6, 8, 12, 15], 
    'weapon': ['sword', 'bow'], 
    'armor': ['naked', 'leather', 'iron'] 
} 

def create_person(person_options): 
    return {k:choice(opts) for k, opts in person_options.items()} 

for _ in range(4): 
    print create_person(person_options) 

:このようにコーディングすることができます。辞書は、定義された動作を持たない状態のグロブです。この状態を収容するクラスを作成する場合、クラスはその状態で動作するメソッドを拡張できます。もちろん、これをすべて説明すると、この回答は本当に本当に長くなる可能性があります。今のところ、コードの古いビットが混乱する可能性がある共有状態から離れるべきであることを認識してください。これを少し訓練すれば、コードを後でリファクタリングするほうがずっと簡単になります。


これはあなたの編集した質問に対処します

from random import choice 
from itertools import count 
from functools import partial 

person_options = { 
    'name': partial(
     choice, ['fred', 'mary', 'john', 'sarah', 'abigail', 'steve']), 
    'location': partial(
     get_location, {'heaven':1, 'hell':2, 'earth':3}), 
    'player id': count(1).next 
} 

def create_person(person_options): 
    return {k:func() for k, func in person_options.items()} 

はしかし、我々は道あなたの元の質問の範囲を超えて、今であり、あなた以外の誰にも役立つことはありません具体的に入ります。 Code Review Stack Exchange

+0

はい、私がやっていることの一部です。私は作成されたそれぞれの人にユニークな数字の 'id'を発行しようとしています。このようにするには、毎回関数に 'id_iterator'を渡して反復し、それを元に戻す必要があります。また、すべてがランダムな選択ではないので、main.py側ではリストを作成する必要があり、次にengine.py側では、リスト内の各項目を変数に割り当てる必要があります。私の 'create_player'と同様のことをする複数の関数間で絶えずそれを行う必要があるのは効率的ではないようです。 – drewd423

+0

あなたの回答に基づいて自分のコードを編集しました。 – drewd423

+0

@Steven_Rumbalskiコメントに基づいて、私は[CodeReviewでスレッドを作成しました](http://codereview.stackexchange.com/questions/159360/football-game-simulation) – drewd423

関連する問題