NameError: name '__file__' is not defined

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
Benutzeravatar
MagBen
User
Beiträge: 799
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

Donnerstag 16. August 2018, 15:51

Ich habe ein Python-Skript test_file.py

Code: Alles auswählen

print( __file__)
Wenn ich das Skipt von der Unix-Shell mit
python test_file.py
ausführe, dann gibt das Skript seinen Dateinamen aus.

Wenn ich es aber in der Python- Shell mit
>>> execfile("test_file.py")
ausführe, dann bekomme ich die Fehlermeldung
NameError: name '__file__' is not defined

Hintergrund:
In einer TestSuite sollen die einzelnen TestCases ihre Testdaten finden, egal von wo der jeweilige TestCase aufgerufen wird, die Testdaten liegen bei den TestCases. Das funktioniert soweit auch alles, außer wenn ich die Tests aus der Python-Shell mit execfile aufrufe.
a fool with a tool is still a fool, www.magben.de, YouTube
Benutzeravatar
__blackjack__
User
Beiträge: 6046
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Donnerstag 16. August 2018, 16:18

Dann ruf es nicht mit `execfile()` auf. :-)

Die Dokumentation von der Funktion weist da auch recht deutlich drauf hin, das kein Modul erstellt wird, wodurch die typischen Attribute eines Moduls natürlich auch nicht existieren:
It is different from the import statement in that it does not use the module administration — it reads the file unconditionally and does not create a new module.
``>>>`` sieht so nach der Standard-Python-Shell aus. In IPython wäre es zum Beispiel kein Problem das Modul einfach als Programm laufen zu lassen. Oder man verwendet so etwas wie pytest und startet die Tests, einzelne Suites, oder einzelne Testfälle damit.

`execfile()` gibt's in Python 3 dann übrigens auch nicht mehr.
long long ago; /* in a galaxy far far away */
__deets__
User
Beiträge: 8121
Registriert: Mittwoch 14. Oktober 2015, 14:29

Donnerstag 16. August 2018, 16:19

Code: Alles auswählen

python2.7 -c 'g = {}; g.update(globals()); g["__file__"] = "foo"; execfile("/tmp/test.py", g)'
loest das Problem. In python3.6 habe ich execfile uebrigens nicht mehr - da solltest du ggf. im Sinne einer Aufwaertkompatibilitaet etwas anderes machen. ZB den import-Mechanismus entsprechend austricksen, so dass du die Module importieren kannst. Dann sollten die aber natuerlich nicht gleich benannt sein.
Benutzeravatar
__blackjack__
User
Beiträge: 6046
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Donnerstag 16. August 2018, 16:31

Für ``g = {}; g.update(globals());`` eventuell ``g = globals().copy();``.
long long ago; /* in a galaxy far far away */
Sirius3
User
Beiträge: 12008
Registriert: Sonntag 21. Oktober 2012, 17:20

Donnerstag 16. August 2018, 19:47

@__deets__: wenn man schon krude rumhackt, dann wenigstens als Einzeiler:

Code: Alles auswählen

python2.7 -c 'execfile("/tmp/test.py", dict(globals(), __file__="foo"))'
__deets__
User
Beiträge: 8121
Registriert: Mittwoch 14. Oktober 2015, 14:29

Donnerstag 16. August 2018, 21:31

Ich wusste gar nicht, das mein Einzeiler kein Einzeiler war. Aber der kürzere Penis gewinnt?
Benutzeravatar
MagBen
User
Beiträge: 799
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

Samstag 18. August 2018, 06:31

"Gefällt mir"
haben wir hier leider nicht.
Vielen Dank an alle Mitwirkenden, dafür dass ich das wunderbare Python-Feature __file__ überall nutzen kann.
a fool with a tool is still a fool, www.magben.de, YouTube
Antworten