Seite 1 von 1
try...except import error
Verfasst: Sonntag 17. Januar 2010, 13:17
von Panke
edit (jens): Abgetrennt von: http://www.python-forum.de/topic-21571.html
Und wenn wir schon mal dabei sind: Jeder Block ist automatisch auch ein Try-Block:
Magst Du mal ein PEP schreiben? Das halte ich für eine gute Idee.
Verfasst: Sonntag 17. Januar 2010, 13:57
von BlackJack
@Panke: Ich weiss nicht -- das wird bei Schleifen und ``else`` IMHO ein wenig unübersichtlich.
Code: Alles auswählen
for a in b:
spam(a)
else:
print 'Buh'
except Exception, e:
raise
else:
print 'Arrr!'
Und hier dann vollends:
Code: Alles auswählen
if c:
ham(x)
except Exception, e:
raise
else:
parrot(x)
Gehört hier das ``else`` zum ``if`` oder zu ``except``? Und wie würde man die jeweils andere Zuordnung ausdrücken müssen? Dann doch wieder in der alten Form mit explizitem ``try``?
Verfasst: Sonntag 17. Januar 2010, 15:37
von Defnull
Panke: In Ruby gibt es das schon, man könnte das einfach übernehmen (die haben sich da bereits ne menge Gedanken drum gemacht).
BlackJack: Der ganze if-elif-else block ist nur ein try-block.
Code: Alles auswählen
if: pass
elif: pass
else: pass
except: pass
# Ist das gleiche, wie
try:
if: pass
elif: pass
else: pass
except: pass
Verfasst: Sonntag 17. Januar 2010, 15:41
von cofi
Naja das Problem ist, dass ein `except`-Zweig auch einen `else`-Zweig haben kann.
Ich finde auch, dass das recht schnell unuebersichtlich werden kann.
Verfasst: Sonntag 17. Januar 2010, 16:48
von jbs
Mal wieder etwas off-topic geraten

.
Ich würde sowas schick finden:
Code: Alles auswählen
try:
import a
except ImportError:
import b
except ImportError:
import c
Verfasst: Sonntag 17. Januar 2010, 18:18
von lunar
Wofür soll das denn gut sein?!
Verfasst: Sonntag 17. Januar 2010, 18:35
von jbs
Man hat es ja immer wieder, dass Module nicht vorhanden sind, bzw. anders heißen. Und irgendwie finde ich es nicht so schön dann sowas wie
Code: Alles auswählen
try:
import a
except ImportError:
try:
import b
except ImportError:
try:
import c
except Import Error:
pass
zu haben. Besonders, wenn es dann noch unübersichtlicher wird. So muss ich dann auf verschiedene Einrückungsebenen achten und das ganze sieht für mich dann nicht so klar strukturiert aus. Wenn ich alle excepts auf einer Ebene habe, wirkt das IMHO geordneter.
Verfasst: Sonntag 17. Januar 2010, 18:45
von BlackJack
@jbs: Woran soll sich das Verhalten denn festmachen, dass *Du* gerne hättest, von einem Konstrukt was bereits eine andere Bedeutung *hat*? Daran, dass in allen ``except``s die gleiche Ausnahme behandelt wird!? Das ist extrem undurchsichtig:
Was bedeutet dass denn nun? Kann man gar nicht sagen ohne zu wissen ob `A` und `B` an verschiedene Objekte gebunden sind oder nicht.
Dein Problem kann man mit `__import__()` und einer Schleife lösen. Wenn man es oft braucht, kann man es sogar in eine Funktion stecken.
Verfasst: Sonntag 17. Januar 2010, 19:02
von Defnull
jbs hat geschrieben:Man hat es ja immer wieder, dass Module nicht vorhanden sind, bzw. anders heißen. Und irgendwie finde ich es nicht so schön dann sowas wie
Code: Alles auswählen
try:
import a
except ImportError:
try:
import b
except ImportError:
try:
import c
except Import Error:
pass
Code: Alles auswählen
for mod in ('a','b.x','c'):
try:
globals()[mod.split('.')[0]] = __import__(mod)
except ImportError:
pass
Verfasst: Montag 18. Januar 2010, 09:18
von mkesper
@Defnull: Eventuell möchte man nur ein Modul laden (cElementtree etc.):
Code: Alles auswählen
for mod in ('a','b.x','c'):
try:
globals()[mod.split('.')[0]] = __import__(mod)
break
except ImportError:
pass
Verfasst: Montag 18. Januar 2010, 16:57
von derdon
Und wenn man es noch eleganter machen möchte, dann so (weil im try-Block immer so wenig wie möglich stehen sollte):
Code: Alles auswählen
for mod in ('a','b.x','c'):
try:
globals()[mod.split('.')[0]] = __import__(mod)
except ImportError:
pass
else:
break
Verfasst: Montag 18. Januar 2010, 21:40
von BlackJack
@derdon: Ich finde es so schwerer zu lesen, weil das ``break`` jetzt so weit von dem Punkt weg steht, an dem ich eigentlich ganz gerne ausdrücken würde "wenn die Zeile drüber klappt, dann hier *sofort* aus der Schleife aussteigen". Komplexer sieht's durch den zusätzlichen Zweig auch aus. Und man minimiert ja den Quelltext in dem Block nicht grundlos, sondern weil man nicht möchte, dass irgendein anderer Code in dem Block eine Ausnahme auslöst und man im ``except`` dann nicht mehr so eindeutig weiss, was *genau* die Quelle war. Da ist ``break`` total "ungefährlich".
Verfasst: Montag 18. Januar 2010, 22:53
von snafu
Ein anderer Ansatz:
Code: Alles auswählen
def first_working_module(*modnames):
for name in modnames:
try:
return __import__(name)
except ImportError:
continue
Gedacht ist das Ordnen nach "Wichtigkeit" (z.B. C-Version zuerst) und das Binden an einen Namen. Wenn kein Modul-Import klappt, wird `None` an den Namen gebunden, was man ja dann bei Bedarf prüfen kann.
Verfasst: Dienstag 19. Januar 2010, 13:24
von mkesper
Der Vorschlag gefällt mir. Auch der Modulname ergibt direkt einen Sinn!
