Mam dwie różne funkcje, które wychwytują te same wyjątki, na przykład:
def func1():
try:
# ...do something
except FileNotFoundError as e:
print(e)
except NotADirectoryError as e:
print(e)
def func2():
try:
# ...do something else
except FileNotFoundError as e:
print(e)
except NotADirectoryError as e:
print(e)
Jak mogę uniknąć pisania tych identycznych wyjątków dla każdej funkcji?
Mój idealny scenariusz byłby taki:
def func1():
# ... do something while catching those exceptions without explicitly stating them here.
def func2():
# ... do something while catching those exceptions without explicitly stating them here.
2 odpowiedzi
Możesz to zrobić za pomocą dekoratorów, ale ogólnie rzecz biorąc, obsługa wyjątków wewnątrz metod funkcji lub klas jest złą praktyką. Wyjątki powinny być zgłaszane w funkcji / metodach i powinny być obsługiwane w zakresie zewnętrznym.
Niemniej jednak kod wygląda następująco:
# create decorator function it can be used in any class, with any function or method:
def my_decorator(f):
def decorated_func(*args, **kwargs):
try:
f(*args, **kwargs)
except ValueError as e:
print(e)
except TypeError as e:
print(e)
return decorated_func
# some class with some static methods:
class MyClass:
@my_decorator
def __init__(self, x, y):
if x == 5:
raise TypeError("C")
self.x = x
self.y = y
print(self.x/self.y)
@staticmethod
@my_decorator
def test(a, b, c):
if a == 1:
raise ValueError("A")
print(a + b + c)
@staticmethod
@my_decorator
def test_two(a, b):
if b == 1:
raise TypeError("B")
print(a * b)
if __name__ == '__main__':
MyClass.test(a=2, b=2, c=3)
MyClass.test(a=1, b=2, c=3)
MyClass.test_two(a=1, b=1)
MyClass.test_two(a=2, b=2)
z = MyClass(1, 1)
z2 = MyClass(5, 5)
Właściwie prawidłowy sposób obsługi błędów powinien wyglądać następująco, wszystkie wyjątki są obsługiwane w kodzie „klienta”, a nie w zakresie metod i funkcji. Jest to najlepszy sposób obsługi wyjątków, jeśli zamierzasz używać swojej biblioteki w innych aplikacjach:
def some_f(x, y):
if x == 1:
raise Exception("x = 1 it is bad")
print(x + y)
class SomeClass:
def __init__(self, x, y):
self.x = x
self.y = y
def sum_them(self):
if self.x == 1:
raise Exception("Incorrect x")
print(self.x + self.y)
if __name__ == '__main__':
# so called "client" code
try:
some_f(1, 3)
except Exception as ex:
print(ex)
try:
z = SomeClass(1, 2)
z.sum_them()
except Exception as ex:
print(ex)
Mógłbyś napisać dekoratora.
from functools import wraps
def just_report_file_errors(fn):
@wraps(fn)
def decorator(*args, **kwargs):
try:
return fn(*args, **kwargs)
except FileNotFoundError as e:
print(e)
except NotADirectoryError as e:
print(e)
return decorator
@just_report_file_errors
def func1():
pass # do thing...
@just_report_file_errors
def func2():
pass # do thing...
Podobne pytania
Nowe pytania
python
Python to wielozadaniowy, wielozadaniowy język programowania dynamicznie typowany. Został zaprojektowany tak, aby był szybki do nauczenia się, zrozumienia i użycia oraz wymuszania czystej i jednolitej składni. Należy pamiętać, że Python 2 oficjalnie nie jest obsługiwany od 01-01-2020. Mimo to, w przypadku pytań Pythona specyficznych dla wersji, dodaj znacznik [python-2.7] lub [python-3.x]. Korzystając z wariantu Pythona (np. Jython, PyPy) lub biblioteki (np. Pandas i NumPy), należy umieścić go w tagach.