try...except import error

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
Panke
User
Beiträge: 185
Registriert: Sonntag 18. März 2007, 19:26

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.
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``?
Benutzeravatar
Defnull
User
Beiträge: 778
Registriert: Donnerstag 18. Juni 2009, 22:09
Wohnort: Göttingen
Kontaktdaten:

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
Bottle: Micro Web Framework + Development Blog
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Naja das Problem ist, dass ein `except`-Zweig auch einen `else`-Zweig haben kann.
Ich finde auch, dass das recht schnell unuebersichtlich werden kann.
Benutzeravatar
jbs
User
Beiträge: 953
Registriert: Mittwoch 24. Juni 2009, 13:13
Wohnort: Postdam

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
[url=http://wiki.python-forum.de/PEP%208%20%28%C3%9Cbersetzung%29]PEP 8[/url] - Quak!
[url=http://tutorial.pocoo.org/index.html]Tutorial in Deutsch[/url]
lunar

Wofür soll das denn gut sein?!
Benutzeravatar
jbs
User
Beiträge: 953
Registriert: Mittwoch 24. Juni 2009, 13:13
Wohnort: Postdam

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.
[url=http://wiki.python-forum.de/PEP%208%20%28%C3%9Cbersetzung%29]PEP 8[/url] - Quak!
[url=http://tutorial.pocoo.org/index.html]Tutorial in Deutsch[/url]
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:

Code: Alles auswählen

try:
    spam()
except A:
    ham()
except B:
    parrot()
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.
Benutzeravatar
Defnull
User
Beiträge: 778
Registriert: Donnerstag 18. Juni 2009, 22:09
Wohnort: Göttingen
Kontaktdaten:

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
Bottle: Micro Web Framework + Development Blog
Benutzeravatar
mkesper
User
Beiträge: 919
Registriert: Montag 20. November 2006, 15:48
Wohnort: formerly known as mkallas
Kontaktdaten:

@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
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

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
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".
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

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.
Benutzeravatar
mkesper
User
Beiträge: 919
Registriert: Montag 20. November 2006, 15:48
Wohnort: formerly known as mkallas
Kontaktdaten:

Der Vorschlag gefällt mir. Auch der Modulname ergibt direkt einen Sinn! :)
Antworten