Python-Quellcode in mehrere Dateien aufteilen?

71

Ich habe einen Code, den ich in mehrere Dateien aufteilen möchte. In matlab kann man einfach eine .mDatei aufrufen , und solange sie nicht als etwas Besonderes definiert ist, wird sie einfach so ausgeführt, als ob sie Teil des aufgerufenen Codes wäre. Beispiel (bearbeitet):
test.m (matlab)

function [] = test()
    ... some code using variables ...
    test2

test2.m (matlab)

... some more code using same variables ...

Beim Aufrufen wird testsowohl der Code im Test als auch der Code in test2 ausgeführt.

Gibt es eine ähnliche Möglichkeit für Python, ... some more code ...in eine externe Datei zu schreiben, die einfach so gelesen wird, als ob sie sich in der Datei befindet, aus der sie aufgerufen wird?

Markus
quelle
1
Ja, Sie können Ihre Dateien in verschiedene Module aufteilen und importieren, was Sie benötigen. docs.python.org/tutorial/modules.html
Borgleader
5
Lesen Sie Ihr Lieblings-Python-Tutorial und erfahren Sie mehr über Module
Andreas Jung
von python1_file import *
Shubh

Antworten:

42

Ich untersuche gerade die Verwendung von Modulen in Python und dachte, ich würde die Frage, die Markus in den obigen Kommentaren ("Wie importiere ich Variablen, wenn sie in Module eingebettet sind?") Stellt, aus zwei Perspektiven beantworten:

  1. Variable / Funktion und
  2. Klasseneigenschaft / -methode.

So würde ich das Hauptprogramm f1.py umschreiben, um die Wiederverwendung von Variablen für Markus zu demonstrieren:

import f2
myStorage = f2.useMyVars(0) # initialze class and properties
for i in range(0,10):
    print "Hello, "
    f2.print_world()
    myStorage.setMyVar(i)
    f2.inc_gMyVar()
print "Display class property myVar:", myStorage.getMyVar()
print "Display global variable gMyVar:", f2.get_gMyVar()

So würde ich das wiederverwendbare Modul f2.py umschreiben:

# Module: f2.py
# Example 1: functions to store and retrieve global variables
gMyVar = 0
def print_world():
    print "World!"
def get_gMyVar():
    return gMyVar # no need for global statement 
def inc_gMyVar():
    global gMyVar
    gMyVar += 1  

# Example 2: class methods to store and retrieve properties
class useMyVars(object):
    def __init__(self, myVar):
        self.myVar = myVar
    def getMyVar(self):
        return self.myVar
    def setMyVar(self, myVar):
        self.myVar = myVar
    def print_helloWorld(self):
        print "Hello, World!"

Wenn f1.py ausgeführt wird, sieht die Ausgabe folgendermaßen aus:

%run "f1.py"
Hello, 
World!
Hello, 
World!
Hello, 
World!
Hello, 
World!
Hello, 
World!
Hello, 
World!
Hello, 
World!
Hello, 
World!
Hello, 
World!
Hello, 
World!
Display class property myVar: 9
Display global variable gMyVar: 10

Ich denke, der Punkt für Markus wäre:

  • Um den Code eines Moduls mehrmals wiederzuverwenden, fügen Sie den Code Ihres Moduls in Funktionen oder Klassen ein.
  • Um Variablen, die als Eigenschaften in Modulen gespeichert sind, wiederzuverwenden, initialisieren Sie Eigenschaften innerhalb einer Klasse und fügen Sie die Methoden "getter" und "setter" hinzu, damit Variablen nicht in das Hauptprogramm kopiert werden müssen.
  • Um in Modulen gespeicherte Variablen wiederzuverwenden, initialisieren Sie die Variablen und verwenden Sie Getter- und Setter-Funktionen. Die Setterfunktionen würden die Variablen als global deklarieren.

quelle
68

Sicher!

#file  -- test.py --
myvar = 42
def test_func():
    print("Hello!")

Diese Datei ("test.py") ist in der Python-Terminologie ein "Modul". Wir können es importieren (solange es in unserem PYTHONPATHVerzeichnis zu finden ist). Beachten Sie, dass sich das aktuelle Verzeichnis immer in PYTHONPATHbefindet. Wenn use_testes also aus demselben Verzeichnis ausgeführt wird, in dem es test.pylebt, sind Sie fertig:

#file -- use_test.py --
import test
test.test_func()  #prints "Hello!"
print (test.myvar)  #prints 42

from test import test_func #Only import the function directly into current namespace
test_func() #prints "Hello"
print (myvar)     #Exception (NameError)

from test import *
test_func() #prints "Hello"
print(myvar)      #prints 42

Sie können viel mehr als nur das tun, indem Sie spezielle __init__.pyDateien verwenden, mit denen Sie mehrere Dateien als ein einziges Modul behandeln können. Dies beantwortet jedoch Ihre Frage, und ich nehme an, wir lassen den Rest für ein anderes Mal.

mgilson
quelle
1
Nun, vielleicht ist mein Beispiel nicht so gut. Ich möchte meinen zusätzlichen Code mit all meinen Variablen aufrufen können. Das Importieren des Moduls hilft mir nicht viel, da ich die Variablen übertragen müsste, nein?
Markus
1
Variablen können ebenfalls importiert werden, obwohl dies nicht sehr häufig vorkommt und Sie dies normalerweise nicht möchten ... (siehe mein Update)
mgilson
Hmm ... viel einfacher als ich gedacht hätte!
John Hunt
22

Python hat Import und Namespace, die gut sind. In Python können Sie wie folgt in den aktuellen Namespace importieren:

>>> from test import disp
>>> disp('World!')

Oder mit einem Namespace:

>>> import test
>>> test.disp('World!')
Ali Afshar
quelle
4

Sie können dasselbe in Python tun, indem Sie einfach die zweite Datei importieren. Der Code auf der obersten Ebene wird beim Import ausgeführt. Ich würde vorschlagen, dass dies bestenfalls chaotisch ist und keine gute Programmierpraxis. Sie sollten Ihren Code besser in Modulen organisieren

Beispiel:

F1.py:

print "Hello, "
import f2

F2.py:

print "World!"

Beim Ausführen:

python ./f1.py
Hello, 
World!

Zur Verdeutlichung bearbeiten: Der Teil, den ich als "chaotisch" vorgeschlagen habe, verwendet die importAnweisung nur für den Nebeneffekt der Generierung von Ausgaben, nicht für die Erstellung separater Quelldateien.

Carl Groner
quelle
Wenn ich das import f2in eine Schleife stecke, schreibt es nur World!einmal. Kann ich es irgendwie ändern?
Markus
1
Ich würde die printAnweisung (in f2.py) in eine Funktion einfügen, die Datei nur einmal importieren und Ihre neue Funktion in der Schleife aufrufen.
Carl Groner
Aber hier habe ich Probleme beim Aufrufen des tatsächlichen Codes mit Variablen, die im Hauptcode und in den "Untercodes" benötigt werden
Markus,