2016-08-18 3 views
1

Ich habe eine Funktion, die eine Unterfunktion hat und ich möchte Variablen innerhalb der Unterfunktion initialisieren. Einfach,Setzen von Variablen in einer Funktion (Unterfunktion) aus einer Datei mit einer Variablen Dateiname

file = "foo" 
def outerFunction(): 
    def innerFunction(): 
     var1 = 0 
     var2 = 1 
     var3 = 2 
     print file, var1, var2, var3 
    file = "bar" 
    innerFunction() 
outerFunction() 

Ausgang: bar 0 1 2

Allerdings habe ich eine recht große Anzahl von Variablen in mehreren verschiedenen Dateien und ich möchte sie einfach in die Unterfunktion importieren, wenn die Unterfunktion aufgerufen wird. Angenommen, ich habe eine Datei bar.py mit folgendem Inhalt:

var1=0 
var2=1 
var3=2 

Dann ich den Code ändern

file = "foo" 
def outerFunction(): 
    def innerFunction(): 
     from file import * 
     print file, var1, var2, var3 
    file = "bar" 
    innerFunction() 
outerFunction() 

seinen Dieser zu einem Fehler führen wird, weil Python 2.7 es nicht mag, wenn Sie Verwenden Sie import innerhalb einer Unterfunktion. Anstatt also können wir die __import__ Funktion direkt verwenden:

file = "foo" 
def outerFunction(): 
    def innerFunction(): 
     __import__(file) 
     print file, var1, var2, var3 
    file = "bar" 
    innerFunction() 
outerFunction() 

Die Importmethode hier funktioniert, aber die Variablen nicht immer tatsächlich machen es in die Variablenliste der Unterfunktion, was zu einem Fehler, wenn ich zu drucken gehen die raus. Jetzt weiß ich, dass ich den Code zu

file = "foo" 
def outerFunction(): 
    def innerFunction(): 
     f = __import__(file) 
     print file, f.var1, f.var2, f.var3 
    file = "bar" 
    innerFunction() 
outerFunction() 

ändern kann und es wird peachy arbeiten. Das ist aber nicht die Lösung, nach der ich suche. Ich möchte in der Lage sein, diese Funktionen zu importieren, ohne den Rest meines Codes zu ändern. Gibt es bessere Lösungen für dieses Problem?

+0

Warum können Sie nicht Datei und Objekt erstellen und dann instanziieren? Dann könnten Sie einfach file.property (file.var1) verwenden oder sogar eine Getter-Funktion verwenden, wenn Sie Berechnungen durchführen möchten? – kyle

+0

Sie scheinen etwas Verwirrung über das Python-Import-System zu haben. "Python 2.7 mag es nicht, wenn Sie den Import in eine Unterfunktion verwenden." Nein...In Python jeder Version können Sie unabhängig vom Gültigkeitsbereich keine Variablen in import-Anweisungen verwenden. "Die Importmethode funktioniert hier, aber die Variablen werden nicht zum lokalen Bereich hinzugefügt." Nun, nein, so funktioniert 'import x' in keiner Situation. Ich verstehe deinen dritten Punkt nicht wirklich. –

+2

Wenn dies nur Einstellungen sind, sollten Sie sie vielleicht analysieren, anstatt zu versuchen, sie auszuführen. Zum Beispiel mit [configparser] (https://docs.python.org/3/library/configparser.html) – spectras

Antwort

0

Aus Wartbarkeitsgründen ist es am besten, das Modul zu importieren und dann auf die Variablen des Moduls zu verweisen. Es ist leicht zu sehen, woher die Variablen kommen.

from module import * ist verpönt, da es schwer nachvollziehbar ist, woher die Variablen kommen, insbesondere wenn mehrere Module Variablen mit demselben Namen enthalten. from module import * ist in einer Funktion nicht möglich, da lokale Variablen in Python funktionieren. Lokale Variablen werden auf dem Stack gespeichert, und wenn Python nicht weiß, wie viele Variablen es gibt, kann es keinen Platz auf dem Stack zuweisen.

Wie auch immer, Sie können tun, was Sie fragen. Aber du solltest nicht. Die Idee dahinter ist, die Variablen, auf die verwiesen wird, als globale Variablen zu belassen und Ihre Globals entsprechend zu aktualisieren, wenn die Funktion startet. z.B.

from importlib import import_module 

file_ = "foo" 
def outer(): 
    def inner(): 
     m = import_module(file_) # import module whose name is the contents of file_ 
     globals().update(m.__dict__) # add module's globals to our own 
     print(file_, var0, var1, var2) 
    file_ = "bar" 
    inner() 
outer() 

Dies ist eine schreckliche Idee, da jede innere Funktion wird die gleiche Menge von Globals teilen und mögliche können Variablen mit dem gleichen Namen überschreiben. Dies führt zu Problemen, wenn inner Funktionen gleichzeitig ausgeführt werden oder wenn Variablen überschrieben werden, die von dem Modul benötigt werden, das outer definiert hat. Es ist möglich, dies zu überwinden, indem man jede inner Funktion so verändert, dass sie ihren eigenen einzigartigen Satz von Globalen verwendet, aber dies ist ein schrecklicher Hack und hauptsächlich enthalten, um zu zeigen, wie dies möglich ist.

from importlib import import_module 
from types import FunctionType 

file_ = "foo" 
def outer(): 
    def inner(): 
     m = import_module(file_) 
     globals().update(m.__dict__) 
     print(file_, var0, var1, var2) 
    # redefine inner with new globals 
    inner = FunctionType(inner.__code__, 
     dict(import_module=import_module, __builtins__=__builtins__), # new globals 
     inner.__name__, inner.__defaults__, inner.__closure__ 
    ) 
    file_ = "bar" 
    inner() 
outer() 
Verwandte Themen