2017-03-21 2 views
0

Ich versuche, verschiedene Funktionen in meinem Programm zu trennen, um die Dinge ordentlich zu halten. Und ich bleibe stecken und versuche, Variablen zu verwenden, die in einem Modul in einem anderen Modul erstellt wurden. Ich habe versucht, global list_of_names zu verwenden, aber es hat nicht funktioniert, und ich habe gelesen, dass es empfehlenswert ist, dies sowieso nicht zu tun.Die beste Methode, Variablen in Modulen zu verwenden? (Python3)

Unten ist ein Beispiel meines Codes. Meiner Meinung nach ist es nicht sinnvoll, list_of_names als Funktionsargument zu übergeben, da es neben den eigentlichen Argumenten, die übergeben werden, mehrere andere Variablen gibt, mit denen ich dies tun muss.

Leider, auch wenn ich read_json in engine.py verschieben würde, hätte ich immer noch das gleiche Problem in main.py, da ich auch dort auf list_of_names verweisen muss.

# 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: Hier ist mein neuer Code. Für mich scheint dies nicht effizient zu sein, die Parameterliste zu erstellen und sie dann innerhalb der Funktion zu dekonstruieren. (Ich weiß, dass ich Variablennamen für dieses Beispiel wiederverwende). Dann muss ich einige dieser Parameter an andere Funktionen übergeben.

# 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

gestellt. Versuchen Sie nicht, dieselbe Variable für mehrere Module zu verwenden. Sie sollten nicht einmal versuchen, die gleiche Variable über mehrere Funktionen hinweg zu verwenden. Erfahren Sie mehr über Funktionsargumente und Rückgabewerte, die fast immer die richtige Methode sind, um Daten zwischen Funktionen zu übergeben. – user2357112

+0

Zusammengefasst mit dem oben genannten, wie wäre es mit einigen OOP (Object Oriented Programming) Struktur in Ihrem Code? Dadurch wird Ihr Code leichter lesbar, wartungsfreundlicher und wiederverwendbar. – 0xDEFACED

+0

@StevenRumbalski @ user2357112 Meinst du etwas wie 'create_person (mylist)'? Denn wie gesagt, es ist nicht praktisch, da ich auf diese Weise viele Argumente an die Funktion übergeben müsste. – drewd423

Antwort

2

Im Allgemeinen sollten Sie nicht auf gemeinsam genutzten globalen Zustand verlassen werden. Wenn Sie den Zustand teilen möchten, kapseln Sie den Zustand in Objekte ein oder übergeben Sie ihn als Funktionsargumente.

In Bezug auf Ihr spezifisches Problem sieht es so aus, als ob Sie zufällige Wörterbücher aus einer Reihe von Optionen zusammenstellen möchten.

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) 

In Aktion: Es könnte so codiert werden

>>> 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'} 

Beachten Sie, dass ein Wörterbuch wie {'armor': 'naked', 'weapon': 'bow', 'health': 15, 'name': 'steve'} wie es ein Ziel sein könnte wollen aussieht. Ein Wörterbuch ist ein Staatsklumpen ohne definiertes Verhalten. Wenn Sie eine Klasse erstellen, die diesen Status enthält, kann die Klasse Methoden entwickeln, die auf diesen Zustand einwirken. Natürlich könnte die Erklärung all dies zu einer wirklich langen Antwort führen. Im Moment merke nur, dass du dich von dem gemeinsamen Status entfernen solltest, mit dem irgendein altes Bit des Codes umgehen kann. Ein bisschen Disziplin dabei wird Ihren Code viel einfacher später zu refactor machen.


Diese richtet sich Ihre editierten Frage:

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()} 

Allerdings sind wir jetzt weit über den Umfang Ihrer ursprünglichen Frage und den Einstieg in Einzelheiten, die einer anderen Person als nicht hilfreich sein wird. Solche Fragen werden besser unter Code Review Stack Exchange

+0

Ja das ist Teil von dem, was ich mache. Ich versuche auch eine eindeutige numerische ID für jede erstellte Person auszugeben. Um dies auf diese Weise zu tun, müsste ich jedes Mal einen 'id_iterator' an die Funktion übergeben, iterieren und dann zurückgeben. Außerdem ist nicht alles eine zufällige Wahl, also muss ich auf der main.py-Seite die Liste erstellen, dann muss ich auf der Seite von engine.py jedem Element in der Liste eine Variable zuweisen. Es scheint einfach nicht effizient zu sein, dies ständig über mehrere Funktionen hinweg tun zu müssen, die ähnliche Dinge tun wie mein 'create_player'. – drewd423

+0

Bearbeitet meinen Code basierend auf Ihrer Antwort. – drewd423

+0

Basierend auf @Steven_Rumbalski Kommentar, ich [erstellt einen Thread auf CodeReview] (http://codereview.stackexchange.com/questions/159360/football-game-simulation) – drewd423

Verwandte Themen