os.popen/os.system in einer schleife gleichzeitig? (3.2.2)

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
ruiin
User
Beiträge: 20
Registriert: Mittwoch 11. April 2012, 16:31
Wohnort: Essen

Hi,

ich baue immernoch an meinem script für rsync.
Ich lese dabei aus einer list, eine reihe von dicts aus in denen die Parameter für rsync stecken. Bis jetzt hat es auch wie erwartet funktioniert, doch nun hab ich mein shebang auf dem mac auf

Code: Alles auswählen

#!/Library/Frameworks/Python.framework/Versions/3.2/bin/python3
geändert und das script verhält sich nun anders.

Vorher wurde jedes Kommando nach einander ausgeführt. Doch es scheint als würden nun die Positionen gleichzeitig ausgeführt werden, was für mich zur komplikationen führt, da mein rsync-Server eine Limitierung von Verbindungen hat. Doch wie krieg ich das wieder so hin das die Positionen nacheinander ausgeführt werden?

Mein Code:

Code: Alles auswählen

if __name__ == "__main__":
	import os

	command = "rsync -ac"
	
	eventk = { "Name" : "Eventkatalog",
				"Quelle" : "/Volumes/fotos/Veranstaltungen",
				"Ziel" : "rsync://jan@192.168.1.2/backup/eventk" }
	hauptk = { "Name" : "Hauptkatalog",
				"Quelle" : "/Volumes/fotos/Hauptkatalog",
				"Ziel" : "rsync://jan@192.168.1.2/backup/hauptk" }
	nachtk = { "Name" : "Nachtkatalog",
				"Quelle" : "/Volumes/fotos/Nachtclubs",
				"Ziel" : "rsync://jan@192.168.1.2/backup/nachtk" }
	itunes = { "Name" : "iTunes Library",
				"Quelle" : "/Users/Shared/iTunes",
				"Ziel" : "rsync://jan@192.168.1.2/backup/itunes" }
	auftrk = { "Name" : "Auftragskatalog",
				"Quelle" : "/Volumes/fotos/auftrk",
				"Ziel" : "rsync://jan@192.168.1.2/backup/auftrk" }
	
	paare = [itunes, eventk, hauptk, nachtk, auftrk]
	
	for i in paare:
#Diese Ebene ist Platzhalter, dort soll noch ein try...except hin kommen.
		if True:
			print("{} in progress...".format(i["Name"]))
			commando = "{} {}/ {}".format(command, i["Quelle"], i["Ziel"])
			os.system(commando)
			print("...done")
		else:
			print("Fehler bei Datensatz: {}".format(i["Name"]))			
			os.system('echo -e "\a"')
Zuletzt geändert von Anonymous am Sonntag 10. Juni 2012, 13:08, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Code-Tags gesetzt.
BlackJack

@ruiin: `os.system()` wartet bis das ausgeführte Programm, beziehungsweise das Kommando was auf der gestarteten Shell ausgeführt wird, fertig ist. Was Du beobachtest, hat also nichts mit Python zu tun, sondern mit dem Kommando welches Du ausführst.

Ich verstehe ehrlich gesagt sowieso nicht warum Du `os.system()` verwendest. Das sollte man durch `subprocess` ersetzen.

`paare` ist ein Schlechter Name für etwas was mehr als ein paar ist. Die Namen für die einzelnen Wörterbücher scheinen mir auch überflüssig zu sein — das hätte man auch gleich als Liste mit Wörterbüchern anlegen können. Oder sogar als so eine Datenstruktur in eine Konfigurationsdatei im JSON-Format auslagern können.

Noch schlechter ist `i` als Name einer Schleifenvariable die an etwas anderes als ganze Zahlen gebunden wird. Das ist total unerwartet für jeden der etwas länger Programmiert und führt zu Verwirrung und Missverständnissen.

Bei den Platzhaltern bei `format()` könntest Du auch das Wörterbuch als Shlüsselwort-Argumente übergeben und die Schlüsselnamen in den Platzhaltern notieren.

Code: Alles auswählen

In [354]: command
Out[354]: 'rsync -ac'

In [355]: job
Out[355]: {'Name': 'test', 'Quelle': '/home', 'Ziel': '/backup'}

In [356]: '{Name} in progress...'.format(**job)
Out[356]: 'test in progress...'

In [357]: '{0} {Quelle}/ {Ziel}'.format(command, **job)
Out[357]: 'rsync -ac /home/ /backup'
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Alternativ zu Blackjacks Vorschlag kann man sich das `.format()` hier im Fall von `print()` auch gänzlich sparen:

Code: Alles auswählen

print(name, 'in progress...')
ruiin
User
Beiträge: 20
Registriert: Mittwoch 11. April 2012, 16:31
Wohnort: Essen

Stimmt, der Bezeichner "paare" ist so aus der Entwicklung entstanden. War vorher glaub ich eine andere Datenstrucktur hinter die dem Namen gerecht wurde. Das mit dem print() kommt noch daher, das ich mal unter 2.7 mit Python angefangen habe und mich daran erst einmal gewöhnen muss :wink: .

Was ist denn so üblich als Bezeichner in Schleifen? "i" und "n" sind glaub ich durch die Mathematik schon belegt.

Was das Kommando angeht: Ich komm wohl nicht drum rum die Ausgabe des Kommandos zu überprüfen, rsync wirft mir eine Ausgabe aus mit Errorzeile. Auf die muss ich wohl prüfen, damit es nicht so aussieht als würde es laufen.

Werde mir mal subprocess anschauen.

/Edit:
Sytaxfehler bei:

Code: Alles auswählen

for up in dicts:
    commando = "{0} {Quelle}/ {Ziel}".format(command, **up)
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

ruiin hat geschrieben:Stimmt, der Bezeichner "paare" ist so aus der Entwicklung entstanden. War vorher glaub ich eine andere Datenstrucktur hinter die dem Namen gerecht wurde. Das mit dem print() kommt noch daher, das ich mal unter 2.7 mit Python angefangen habe und mich daran erst einmal gewöhnen muss :wink: .
Naja, für den einfachen Fall, dass ein Leerzeichen der Trenner ist, hätte das auch in Python 2.7 ohne `format()` geklappt:

Code: Alles auswählen

print name, 'in progress...'
Vielleicht kanntest du die Variante einfach nur noch nicht. ;)
ruiin hat geschrieben:Sytaxfehler bei:

Code: Alles auswählen

for up in dicts:
    commando = "{0} {Quelle}/ {Ziel}".format(command, **up)
Falls du darauf eine konstruktive Antwort erwartest, dann poste bitte ein Minimalbeispiel, welches deinem tatsächlichen Code entspricht (oder gleich den Originalcode) und bitte auch die komplette Fehlermeldung, samt "Rattenschwanz" (aka Traceback).
BlackJack

@ruiin: Üblich als Bezeichner in Schleifen ist etwas was die Bedeutung der Werte beschreibt, die an den Namen gebunden werden. Also genau wie bei allen anderen Namen. `up` und `dicts` sind da auch schlechte Namen. `up` scheint nicht das englische für „hoch” zu sein, sondern irgendeine Abkürzung‽ Und `dicts` sagt welche Datenstruktur es ist, aber nicht *wofür* das eigentlich steht.

`command` und `commando` sind auch ungünstig. Zu dicht beieinander und `commando` ist vielleicht nicht wirklich passend. Das ist das militärische Kommando oder die Kommandotruppe. ;-) Die Frage ist, ob Du an der Stelle überhaupt einen Namen dafür brauchst.

``rsync`` hat eine recht umfangreiche Sammlung an „exit codes“ auf den man prüfen kann. Soweit ich das sehe steht nur die 0 für „erfolgreich gelaufen”. Das ist oft robuster als irgendwelche Ausgaben zu prüfen, bei denen es zum Beispiel von den Systemeinstellungen abhängen kann, in welcher Sprache die ausgegeben werden. Hier ist auch wieder `subprocess` (ohne ``shell=True``) Vorteilhaft, weil der Exit-Code dann ganz sicher von ``rsync`` stammt und nicht vielleicht auch von der Shell.

Die beiden Zeilen enthalten keinen Syntaxfehler. Der muss woanders sein und dem Übersetzer erst dort aufgefallen sein.
ruiin
User
Beiträge: 20
Registriert: Mittwoch 11. April 2012, 16:31
Wohnort: Essen

Alles einfache Strings, in der Pythonshell ohne list, direkt aus einem dict hat er keine probleme.

Code: Alles auswählen

command = "rsync -nac" 

dicts[0] = { "Name" : "Test", "Quelle" : "/testdir", "Ziel" : "/testdir2" }
dicts[1] = ...

for up in dicts:
    commando = "{0} {Quelle}/ {Ziel}".format(command, **up)
Den Traceback muss ich mal aus den logfiles rauskramen.

/Edit:
Hab mir subprocess inzwischen angeschaut und eingebaut. Bekomme aber wieder einen SyntaxError:
Code:

Code: Alles auswählen

if __name__ == "__main__":
	import subprocess
 
	tool = "rsync"
	option = "-nac"
	
	dicts[0] = { "Name" : "Eventkatalog",
				"Quelle" : "/Volumes/fotos/Veranstaltungen/",
				"Ziel" : "rsync://jan@192.168.1.2/backup/eventk" }
	dicts[1] = { "Name" : "Hauptkatalog",
				"Quelle" : "/Volumes/fotos/Hauptkatalog/",
				"Ziel" : "rsync://jan@192.168.1.2/backup/hauptk" }
	dicts[2] = { "Name" : "Nachtkatalog",
				"Quelle" : "/Volumes/fotos/Nachtclubs/",
				"Ziel" : "rsync://jan@192.168.1.2/backup/nachtk" }
	dicts[3] = { "Name" : "iTunes Library",
				"Quelle" : "/Users/Shared/iTunes/",
				"Ziel" : "rsync://jan@192.168.1.2/backup/itunes" }
	dicts[4] = { "Name" : "Auftragskatalog",
				"Quelle" : "/Volumes/fotos/auftrk",
				"Ziel" : "rsync://jan@192.168.1.2/backup/auftrk" }
	
	for up in dicts:
		try:
			print("{Name} in progress...".format(**up)
			subprocess.check_output([tool, option, up["Quelle"], up["Ziel"]])
			print("...done")
		except subprocess.CalledProcessError:
			print("Fehler bei Datensatz: {}".format(up["Name"]))
			print(subprocess.CalledProcessError.returncode)			
			os.system('echo -e "\a"')
	os.system('echo -e "\a"')
Error:

Code: Alles auswählen

:~ jan$ /var/folders/hn/3xbbx6597nxf4nbwr4yfcqy00000gn/T/Cleanup\ At\ Startup/rsync.py-361095112.598.command.command ; exit;
  File "/private/var/folders/hn/3xbbx6597nxf4nbwr4yfcqy00000gn/T/Cleanup At Startup/rsync.py-361095112.593.command", line 48
    subprocess.check_output([tool, option, up["Quelle"], up["Ziel"]])
             ^
SyntaxError: invalid syntax
logout
/Edit: Mir fällt grad auf das ich die anderen os.system Funktionen ersetzten muss.
BlackJack

@ruiin: Dann schau Dir mal ganz aufmerksam die Zeile davor an.

Ein Wörterbuch mit aufsteigenden ganzen Zahlen die bei Null anfangen als Schlüssel zu bestücken ist ein Hinweis darauf, dass man eigentlich eine Liste verwenden will. Was wäre denn hier der Sinn eines Wörterbuchs?

Du wirst auch Probleme mit dem `format()` und den Schlüsselzugriffen bekommen, denn `up` wird an andere Objekte gebunden als Du das anscheinend vermutest.

``print(subprocess.CalledProcessError.returncode)`` wird nicht funktionieren. Du musst das konkrete Exemplar von dieser Ausnahme mit ``as`` an einen Namen binden und auf *dessen* `returncode`-Attribut zugreifen.

Eine Shell zu starten um dort dann ``echo`` auszuführen um ein ASCII BEL auszugeben ist reichlich umständlich. Zumal die ``-e``-Option AFAIK auch nicht standard ist, also nicht überall funktioniert. Du kannst das Zeichen doch auch einfach in Python per `print()` ausgeben.
ruiin
User
Beiträge: 20
Registriert: Mittwoch 11. April 2012, 16:31
Wohnort: Essen

Ich will über das wörterbuch direkt über Schlüssel auf die Daten zugreifen, doch gleichzeitig will ich verhindern für jeden Abschnitt einen eigenen Bezeichner zu schreiben. Dazu kann man Listen gut über eine for...in Anweisung abarbeiten. Bis jetzt hatte ich mit dieser Strucktur keine Schwierigkeiten. Später will ich die Wörterbücher auch aus einer JSON-Datei automatisch auslesen, da kann ich gar keinen Bezeichner für jedes Wörterbuch generieren. Ich denke ein Wörterbuch für die Wörterbücher zu nutzen erzeugt Komplexität, welche man dann auch in der JSON-Datei abbilden muss.

Bis jetzt bin ich bei einer for...in Anweisung ausgegangen, das, hier "up" wie ein Bezeichner für dicts[0 bis 4] funktioniert, also auf ein Wörterbuch zeigt, so das ich den Bezeichner wie ein Wörterbuch benutzen kann. Da liegt wohl dann auch der SyntaxError. Doch wie gehts richtig?

Also muss ich returncode öffnen wie ein Datenobjekt?

Code: Alles auswählen

with open(subprocess.CalledProcessError, "r") as ecode:
    print(ecode.returncode)
Den übrigen os.system Code hab ich inzwischen weggeworfen. Ich brauch erstmal keine Bell.
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Der Syntaxfehler rührt ganz einfach daher, dass du in der Zeile davor vergessen hast, am Ende eine Klammer zu schließen.
ruiin
User
Beiträge: 20
Registriert: Mittwoch 11. April 2012, 16:31
Wohnort: Essen

oh,

und darauf folgt jetzt ein IndexError wegen der Liste.
Ich probier es mal mit dem Wörterbuch im Wörterbuch

aktueller Code:

Code: Alles auswählen

if __name__ == "__main__":
	import subprocess
 
	tool = "rsync"
	option = "-nac"
	
	syncs = []
	syncs[0] = { "Name" : "Eventkatalog",
				"Quelle" : "/Volumes/fotos/Veranstaltungen/",
				"Ziel" : "rsync://jan@192.168.1.2/backup/eventk" }
	syncs[1] = { "Name" : "Hauptkatalog",
				"Quelle" : "/Volumes/fotos/Hauptkatalog/",
				"Ziel" : "rsync://jan@192.168.1.2/backup/hauptk" }
	syncs[2] = { "Name" : "Nachtkatalog",
				"Quelle" : "/Volumes/fotos/Nachtclubs/",
				"Ziel" : "rsync://jan@192.168.1.2/backup/nachtk" }
	syncs[3] = { "Name" : "iTunes Library",
				"Quelle" : "/Users/Shared/iTunes/",
				"Ziel" : "rsync://jan@192.168.1.2/backup/itunes" }
	syncs[4] = { "Name" : "Auftragskatalog",
				"Quelle" : "/Volumes/fotos/auftrk/",
				"Ziel" : "rsync://jan@192.168.1.2/backup/auftrk" }
	
	for sync in syncs:
		try:
			print("{Name} in progress...".format(**sync))
			subprocess.check_output([tool, option, sync["Quelle"], sync["Ziel"]])
			print("...done")
		except subprocess.CalledProcessError:
			print("Fehler bei Datensatz: {}".format(sync["Name"]))
			print(subprocess.CalledProcessError.returncode)			
Error:

Code: Alles auswählen

:~ jan$ /var/folders/hn/3xbbx6597nxf4nbwr4yfcqy00000gn/T/Cleanup\ At\ Startup/rsync.py-361099921.744.command.command ; exit;
Traceback (most recent call last):
  File "/private/var/folders/hn/3xbbx6597nxf4nbwr4yfcqy00000gn/T/Cleanup At Startup/rsync.py-361099921.739.command", line 16, in <module>
    "Ziel" : "rsync://jan@192.168.1.2/backup/eventk" }
IndexError: list assignment index out of range
logout
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

ruiin hat geschrieben:Also muss ich returncode öffnen wie ein Datenobjekt?

Code: Alles auswählen

with open(subprocess.CalledProcessError, "r") as ecode:
    print(ecode.returncode)
Wie wär's, wenn du dir mal ein bißchen die Grundlagen von Python, insbesondere hinsichtlich der Ausnahmebehandlung, anguckst? `returncode` ist kein dateiartiges Objekt, sondern einfach ein Attribut, auf das man im Fehlerfall folgendermaßen zugreifen kann:

Code: Alles auswählen

[...]
except CalledProcessError as e:
    print(e.returncode)
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

ruiin hat geschrieben:und darauf folgt jetzt ein IndexError wegen der Liste.
Wenn du ein neues Element an eine Liste hängen willst, dann musst du `.append()` auf dem Listenobjekt benutzen. Ein `liste[0] = 'xyz'` funktioniert nur dann, wenn für diesen Index schonmal etwas zugewiesen wurde, was bei deinem Beispiel aber ja nicht der Fall ist.

Wie gesagt: Mach dich am Besten erstmal näher mit Python vertraut. Das sind wirklich Grundlagenprobleme, die du hier hast.
ruiin
User
Beiträge: 20
Registriert: Mittwoch 11. April 2012, 16:31
Wohnort: Essen

bei mir ist das immer eine Frage der Anwendung. Ich kann mir nicht so nen mitp "Taschenbuch" durchlesen, bei mir läuft das über Anwendung. Bis jetzt hab ich einfach zu wenige Projekte um Python anzuwenden.

Aber danke für die Hilfe. Ich werde mal schaun das ich mir die details noch mal zu Gemüte führe.
BlackJack

@ruiin: Es muss ja kein 1000-Seiten-Buch sein, aber ein Tutorial, welches die grundlegenden Kontrollstrukturen und Datentypen enthält, die man in so ziemlich jedem Programm verwendet, wäre schon nicht schlecht. Mit Listen, Wörterbüchern, und vielleicht auch Mengen (`set()`) sollte man sich vertraut machen. Und mit Funktionen, Schleifen, Iteratoren, und Ausnahmebehandlung auch. Das braucht man in jedem nicht-trivialen Programm.
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

ruiin hat geschrieben:bei mir ist das immer eine Frage der Anwendung. Ich kann mir nicht so nen mitp "Taschenbuch" durchlesen, bei mir läuft das über Anwendung.
Ist bei mir genau so, dass ich eher nicht der Theoriemensch bin und auch ungerne theoretische Beispiele nachvollziehe, sondern mir viel lieber an praktischen Aufgabenstellungen neues Wissen erarbeite. Aber die Seite docs.python.org bietet umfangreiche Dokumentationen samt Suchfunktion an, wo du immer als erstes nachgucken solltest, bevor du mit deinen Fragen irgendwann an die Grenze des Nervens stößt (etwas schmeichelhaft ausgedrückt). Zudem ist Google dein Freund. Und gerade für Fragestellungen, die sich nicht so leicht in Suchworte fassen lassen (einfach weil einem nichts prägnantes zum Eingeben einfällt), da empfiehlt sich das Lesen von Tutorials. Hier zum Beispiel zum Thema Listen. Es gibt auch das "offizielle Python-Tutorial" (auch auf deutsch), welches eine ziemlich gute Anlaufstelle ist.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

ruiin hat geschrieben:bei mir ist das immer eine Frage der Anwendung. Ich kann mir nicht so nen mitp "Taschenbuch" durchlesen, bei mir läuft das über Anwendung.
Also lieber Leute frustrieren, damit du nicht lesen musst? Nicht gerade die feine englische Art.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

snafu hat geschrieben:Wenn du ein neues Element an eine Liste hängen willst, dann musst du `.append()` auf dem Listenobjekt benutzen.
Und noch als Zusatz: Sofern die Länge der Liste bei der Erstellung bekannt ist (und das ist bei dir der Fall), dann kann man natürtlich direkt Listenliterale bei der Erstellung benutzen:

Code: Alles auswählen

syncs = [
    {"Name": "Eventkatalog", ...},
    {"Name": "Hauptkatalog", ...},
    {"Name": "Nachtkatalog", ...},
]
Das Komma am Ende tut übrigens nicht weh und erleichtert das Copy&Paste für weitere Zeilen.

Als spätere Optimierung liesse sich natürlich wunderbar ein Named Tuple verwenden, aber guck du erstmal, dass dein Programm überhaupt mal lauffähig wird. ;)
ruiin
User
Beiträge: 20
Registriert: Mittwoch 11. April 2012, 16:31
Wohnort: Essen

@Leonidas: Ich hatte nicht die Absicht hier Leute zu frustrieren. Ich hab schon ein paar Anleitungen durch, doch erst mit der Anwendung findet das bei mir Eingang. So sind so manche O'Reilly Bücher super geschrieben und haben Anwendungen die man auch nachprogrammieren kann, doch lernen tu ich erst wenn ich Fehler mache. So Beispiele sind dafür viel zu Flach um wirklich wo hängen zu bleiben. Bei Syntaxfehler übersieht man oft seine eigenen offensichtlichen Fehler und die Sache mit der Liste, das wusste ich einfach nicht. Auch hab ich momentan etwas Probleme mit dem Umstieg von 2.7 auf 3.2, hab mit 2.7 angefangen etwas zu scripten, und will aber eher 3.2 lernen. Ich finds es übrigens super hier Leute zu finden die weiter wissen wo Bücher versagen und ich verzweifel :wink: .

@Snafu: Der Code läuft und hab auch mal die Kommatar eingesetzt. Ich benutze erst einmal list.append() um die Liste zu erstellen, wenn ich dan so weit bin eine Art config-Datei zu benutzen muss ich die Abschnitte nur aneinander hängen. Danke vielmals.


Der Code:

Code: Alles auswählen

if __name__ == "__main__":
	import subprocess
 
	tool = "rsync"
	option = "-nav"
	
	syncs = []
	syncs.append({
				 "Name" : "Eventkatalog",
				"Quelle" : "/Volumes/fotos/Veranstaltungen/",
				"Ziel" : "rsync://jan@192.168.1.2/backup/eventk",
})
	syncs.append({
				"Name" : "Hauptkatalog",
				"Quelle" : "/Volumes/fotos/Hauptkatalog/",
				"Ziel" : "rsync://jan@192.168.1.2/backup/hauptk",
})
	syncs.append({ 
				"Name" : "Nachtkatalog",
				"Quelle" : "/Volumes/fotos/Nachtclubs/",
				"Ziel" : "rsync://jan@192.168.1.2/backup/nachtk",
})
	syncs.append({ 
				"Name" : "iTunes Library",
				"Quelle" : "/Users/Shared/iTunes/",
				"Ziel" : "rsync://jan@192.168.1.2/backup/itunes",
})
	syncs.append({ 
				"Name" : "Auftragskatalog",
				"Quelle" : "/Volumes/fotos/auftrk/",
				"Ziel" : "rsync://jan@192.168.1.2/backup/auftrk",
})
	
	for sync in syncs:
		try:
			print("{Name} in progress...".format(**sync))
			subprocess.check_output([tool, option, sync["Quelle"], sync["Ziel"]])
			print("...done")
		except subprocess.CalledProcessError as e:
			print("Fehler bei Datensatz: {}".format(sync["Name"]))
			print(e.returncode)
BlackJack

@ruiin: Warum machst Du das so umständlich mit den `append()`-Aufrufen? Schreib doch einfach gleich die Liste mit den Wörterbüchern dort hin, statt eine leere Liste und dann für jedes Wörterbuch `append()` aufzurufen.
Antworten