J'ai travaillé en Python et j'ai rencontré un problème qui doit être commun. J'ai cinq déclarations qui tombent toutes dans un piège commun d'élever FooException et BarException. Je veux exécuter chacun d'entre eux, en gardant contre ces exceptions mais continuant à traiter même si une exception est levée après une certaine manipulation est faite. Maintenant, je pourrais faire comme ceci:Exceptions Python Contrôle/flux Problème
try:
foo()
except (FooException, BarException):
pass
try:
bar()
except (FooException, BarException):
pass
try:
baz()
except (FooException, BarException):
pass
try:
spam()
except (FooException, BarException):
pass
try:
eggs()
except (FooException, BarException):
pass
mais c'est vraiment verbeux et en violation extrême de DRY. est quelque chose comme une solution plutôt force brute et évidente:
def wish_i_had_macros_for_this(statements, exceptions, gd, ld):
""" execute statements inside try/except handling exceptions with gd and ld
as global dictionary and local dictionary
statements is a list of strings to be executed as statements
exceptions is a list of strings that resolve to Exceptions
gd is a globals() context dictionary
ld is a locals() context dictionary
a list containing None or an Exception if an exception that wasn't
guarded against was raised during execution of the statement for each
statement is returned
"""
s = """
try:
$STATEMENT
except (%s):
pass
""" % ','.join(exceptions)
t = string.Template(s)
code = [t.substitute({'STATEMENT': s}) for s in statements]
elist = list()
for c in code:
try:
exec c in gd, ld
elist.append(None)
except Exception, e:
elist.append(e)
return elist
Avec l'utilisation le long des lignes de:
>>> results = wish_i_had_macros_for_this(
['foo()','bar()','baz','spam()','eggs()'],
['FooException','BarException'],
globals(),
locals())
[None,None,None,SpamException,None]
Y at-il une meilleure façon?
Le problème avec ces deux solutions est que mes déclarations ne sont pas strictement appelables. Maintenant, je pourrais suivre cela et les rendre appelables en définissant funcs ou lambdas, mais est-ce moins mauvais que ce que je fais ci-dessus? –
@BrandonAdams: ce sera mieux si vous montrez le vrai code. Mais en général, 'exec 'est un outil spécial, et devrait plutôt être évité. –