without - python try zerodivisionerror
Declaraciones de prueba anidadas en python? (6)
¿Qué tal encapsular las llamadas en una función?
def method_1_2_or_3():
try:
a.method1()
return
except AttributeError:
pass
try:
a.method2()
return
except AttributeError:
pass
try:
a.method3()
except AttributeError:
raise
¿Hay alguna manera más agradable de hacer lo siguiente?
try:
a.method1()
except AttributeError:
try:
a.method2()
except AttributeError:
try:
a.method3()
except AttributeError:
raise
Parece bastante desagradable y preferiría no hacerlo:
if hasattr(a, ''method1''):
a.method1()
else if hasattr(a, ''method2''):
a.method2()
else if hasattr(a, ''method3''):
a.method3()
else:
raise AttributeError
Mantener la máxima eficiencia.
Si está utilizando un objeto de estilo nuevo:
methods = (''method1'',''method2'',''method3'')
for method in methods:
try:
b = a.__getattribute__(method)
except AttributeError:
continue
else:
b()
break
else:
# re-raise the AttributeError if nothing has worked
raise AttributeError
Por supuesto, si no está utilizando un objeto de estilo nuevo, puede probar __dict__
lugar de __getattribute__
.
EDITAR: Este código puede resultar ser un lío gritando. Si __getattribute__
o __dict__
no se encuentra, adivina qué tipo de error se plantea.
Tal vez podrías intentar algo como esto:
def call_attrs(obj, attrs_list, *args):
for attr in attrs_list:
if hasattr(obj, attr):
bound_method = getattr(obj, attr)
return bound_method(*args)
raise AttributeError
Lo llamarías así:
call_attrs(a, [''method1'', ''method2'', ''method3''])
Esto intentará llamar a los métodos en el orden en que están en la lista. Si desea pasar cualquier argumento, puede pasarlos después de la lista como sigue:
call_attrs(a, [''method1'', ''method2'', ''method3''], arg1, arg2)
Un ligero cambio en el segundo parece bastante agradable y simple. Realmente dudo que noten alguna diferencia de rendimiento entre los dos, y esto es un poco mejor que un try / exceptts anidado
def something(a):
for methodname in [''method1'', ''method2'', ''method3'']:
try:
m = getattr(a, methodname)
except AttributeError:
pass
else:
return m()
raise AttributeError
La otra forma muy legible es hacer ..
def something(a):
try:
return a.method1()
except:
pass
try:
return a.method2()
except:
pass
try:
return a.method3()
except:
pass
raise AttributeError
Si bien es largo, es muy obvio lo que hace la función ... El rendimiento realmente no debería ser un problema (si algunas declaraciones try / except ralentizan notablemente el script, es probable que haya un problema mayor con la estructura del script)
Una solución compacta
getattr(a, ''method1'',
getattr(a, ''method2'',
getattr(a, ''method3'')))()
method = (
getattr(a, ''method1'', None) or
getattr(a, ''method2'', None) or
getattr(a, ''method3'')
)
method()
Esto primero buscará method1
, luego method2
, luego method3
. La búsqueda se detendrá tan pronto como se encuentre uno de ellos. Si no se encuentra ninguno de los métodos, el último getattr
generará una excepción.