Wie sebix schon geschrieben hat entsteht das grundsätzliche Problem dadurch, dass der Syntax-Check in dem Fall schon vor der Ausführung des Codes passiert (nämlich wenn aus dem Quellcode der Byte Code erstellt wird). Daher greift dein try ... except Block nicht. Das bedeutet, dass du Syntaxfehler nur dann im Skript abfangen kannst, wenn der Code mit dem Syntax-Fehler erst zur Laufzeit in Byte Code übersetzt werden soll.
Die Variante mit
exec sähe z.B. so aus:
1
2
3
4
5
6
7
8
9
10
11
12 | #!/usr/bin/env python3
# -*- coding: utf-8 -*-
try:
exec("""
import sys
falcheZeile
#Hier passiert dann was
""")
except Exception as e:
print ('scripterror')
print (e)
|
liefert eine dementsprechende Fehlermeldung, wobei man beachten muss, dass sich die Zeilennummern auf den von exec ausgewerteten String beziehen, nicht auf die Datei:
$ ./test.py
scripterror
unexpected indent (<string>, line 2)
Du kannst den Code mit potentiellen Syntax-Fehlern auch in eine eigene Datei packen und dann importieren (denk daran, dass import-Statements in dieser Datei keinen Effekt auf den Namespace im Haupt-Modul haben).
| # bad_code.py
# -*- coding: utf-8 -*-
def foo():
import sys
falcheZeile
#Hier passiert dann was
|
| #!/usr/bin/env python3
# -*- coding: utf-8 -*-
# main.py
try:
import bad_code
bad_code.foo()
except Exception as e:
print ('scripterror')
print (e)
|
Das liefert dann
$ ./main.py
scripterror
unindent does not match any outer indentation level (bad_code.py, line 6)
Es ist IMHO normalerweise ziemlich unsinnig Syntaxfehler abzufangen, da es klare Programmierfehler sind, die einem eigentlich bei dem einfachsten denkbaren Test (Code als Bytecode übersetzen, was automatisch passiert, wenn man ein Stück Code ausführt bzw. importiert) auffallen sollten, bevor das Programm in den Händen eines Nutzers landet.
Das kann auch ein Linter wie pylint für dich automatisch in einem brauchbaren Editor bzw. einer IDE automatisch überprüfen. Wenn man gezielt Byte Code (.pyc Dateien) aus dem Quellcode erzeugen will, kann man py_compile bzw. compileall nutzen, also z.B.:
| >>> import py_compile
>>> py_compile.compile('bad_code.py')
Sorry: IndentationError: unindent does not match any outer indentation level (bad_code.py, line 6)
|
bzw. in der Shell:
$ python3 -m py_compile bad_code.py
Sorry: IndentationError: unindent does not match any outer indentation level (bad_code.py, line 6)