|
Size: 6776
Comment: Traduzione in italiano del documento originale in inglese
|
Size: 9265
Comment: Steven D'Aprano's comment pro-exception he posted on the python list.
|
| Deletions are marked like this. | Additions are marked like this. |
| Line 3: | Line 3: |
| = Manutenere le Eccezioni = |
|
| Line 6: | Line 4: |
Un semplice modo per manutenere le eccezioni è usare il blocco "try-except" --> "prova all'innfuoridi" |
|
| Line 19: | Line 15: |
Se volete esaminare l'eccezione dal codice,guardate qua: |
|
| Line 34: | Line 28: |
| == Prendiamo il controllo generale del codice == |
|
| Line 38: | Line 30: |
| Talvolta,potete prendere "all" tutti gli errori che è possibile generare, ma di solito non è possibile.Nella mag- gior parte dei casi,quanto specificate tanto è possibile (Wiki:CatchWhatYouCanHandle). Nel primo caso, se stavate usando una clausola eccezione incontrata e l'utente ha premuto Ctrl-C,generando una KeyboardInterrupt (interruzione da tastiera),non desiderate che il programma emetta il messaggio "divide by zero"--> (divisione per zero.) |
|
| Line 44: | Line 32: |
| Tuttavia,ci sono alcune situazioni in cui è meglio prendere ''all'' tutti gli errori |
|
| Line 47: | Line 33: |
| Per esempio, supponiamo che scriviate un modulo per un servizio web. Vorrete che le informazioni inerenti gli errori sia riportate in una pagina web, e il server continui a girare,se tutto ciò è possibile.Ma voi non avete idea che tipo di errori dovete mettere nbel vs codice. |
|
| Line 51: | Line 35: |
| In una situazio9ne di questo tipo,il codice potrebbe essere simile a questo: | |
| Line 65: | Line 48: |
| MoinMoin software è un buon esempio su dove in generale catturare gli errori. Se scrivte Moin``Moin macro estensione,e diamo avvio ad un errore,Moin''Moin prepareà un dettagliato rapporto circa l'errore e la catena di eventi che conduce a lui. Il software Python deve essere abilitato a catturare tutti gli errori, e li spedisce poi alla pagina web. |
|
| Line 69: | Line 50: |
| == Ricerca di Nomi Specifici di Eccezioni == |
|
| Line 73: | Line 52: |
| Eccezioni Standard che possono essere emesse sono dettaglaite in questo sito: |
|
| Line 78: | Line 55: |
| Osservate la Classe documentazione per trovare che eccezioni una data classe può emeyttere. | |
| Line 82: | Line 58: |
| = Vedi Anche = |
|
| Line 86: | Line 60: |
| Su questa wiki:WritingExceptionClasses, TracebackModule. |
|
| Line 90: | Line 62: |
| Per idde generali(non specificate in Python) circa le eccezioni,consulatre Wiki:ExceptionPatterns. |
|
| Line 94: | Line 64: |
| = Per scrivere sull'argomento......." * Give example of IOError, and interpreting the IOError code. * Dammi un esempio di IOError, e interpretiamo il codice di errore |
* Give example of IOError, and interpreting the IOError code. |
| Line 102: | Line 68: |
| * Dammi un esempio di eccezioni multiple. Manteniamo le eccezioni multiple in linea |
|
| Line 106: | Line 70: |
| * Mostra come usare "else" e "finalità" |
|
| Line 110: | Line 72: |
| * Mostra come continuare con un "rialzo" |
|
| Line 114: | Line 74: |
| = Domande = |
|
| Line 118: | Line 76: |
| == Manutenzione generale degli errori == |
|
| Line 121: | Line 77: |
Nella sezione "manutenzione generale degli errori", si è detto che per la cattura degli errori userete questo codice: |
|
| Line 136: | Line 90: |
| Tuttavia in origine era: |
|
| Line 148: | Line 100: |
| Alcune indicano che "except" catturano piu di un semplice "except Exception, e." |
|
| Line 152: | Line 102: |
| ''Perchè è questo il caso??.Qual è la differenza?'' --LionKimbro. |
|
| Line 156: | Line 104: |
| Per ora ( nella ver. 2.3) l'eccezionempm ha ereditato da Exception. Allora pianifichiamo 'except:' catturiamo tutte le eccezioni,non solo quelle di sistema. -- MikeRovner [[DateTime(2004-01-19T05:49:19Z)]] |
|
| Line 161: | Line 106: |
| == Prendiamo utili Informazioni da una eccezione == |
|
| Line 165: | Line 108: |
| Cosi si pò avere qualcosa di simile: |
|
| Line 174: | Line 115: |
| ... e Python soffia indietro | |
| Line 181: | Line 121: |
| .... e cosi,naturalmente chiederete, "bene che, cosa 'era' in {{{d}}}?" |
|
| Line 184: | Line 122: |
== Isn't it better to prevent then to remediate? == > http://www.joelonsoftware.com/items/2003/10/13.html Joel Spolsky might be a great C++ programmer, and his advice on user interface design is invaluable, but Python is not C++ or Java, and his arguments about exceptions do not hold in Python. Joel argues: "They are invisible in the source code. Looking at a block of code, including functions which may or may not throw exceptions, there is no way to see which exceptions might be thrown and from where. This means that even careful code inspection doesn't reveal potential bugs." I don't quiet get this argument. In a random piece of source code, there is no way to tell whether or not it will fail just by inspection. If you look at: x = 1 result = myfunction(x) you can't tell whether or not myfunction will fail at runtime just by inspection, so why should it matter whether it fails by crashing at runtime or fails by raising an exception? Joel's argument that raising exceptions is just a goto in disguise is partly correct. But so are for loops, while loops, functions and methods! Like those other constructs, exceptions are gotos tamed and put to work for you, instead of wild and dangerous. You can't jump *anywhere*, only highly constrained places. Joel also writes: "They create too many possible exit points for a function. To write correct code, you really have to think about every possible code path through your function. Every time you call a function that can raise an exception and don't catch it on the spot, you create opportunities for surprise bugs caused by functions that terminated abruptly, leaving data in an inconsistent state, or other code paths that you didn't think about." This is a better argument for *careful* use of exceptions, not an argument to avoid them. Or better still, it is an argument for writing code which doesn't has side-effects and implements data transactions. That's a good idea regardless of whether you use exceptions or not. Joel's concern about multiple exit points is good advice, but it can be taken too far. Consider the following code snippet: def myfunc(x=None): result = "" if x is None: result = "No argument given" elif x = 0: result = "Zero" elif 0 < x <= 3: resutl = "x is between 0 and 3" else: result = "x is more than 3" return result There is no benefit in deferring returning value as myfunc does, just for the sake of having a single exit point. "Have a single exit point" is a good heuristic for many functions, but it is pointless make-work for this one. (In fact, it increases, not decreases, the chances of a bug. If you look carefully, myfunc above has such a bug. Used correctly, exceptions in Python have more advantages than disadvantages. They aren't just for errors either: exceptions can be triggered for exceptional cases (hence the name) without needing to track (and debug) multiple special cases. Lastly, let me argue against one of Joel's comments: "A better alternative is to have your functions return error values when things go wrong, and to deal with these explicitly, no matter how verbose it might be. It is true that what should be a simple 3 line program often blossoms to 48 lines when you put in good error checking, but that's life, and papering it over with exceptions does not make your program more robust." Maybe that holds true for C++. I don't know the language, and wouldn't like to guess. But it doesn't hold true for Python. This is how Joel might write a function as a C programmer: def joels_function(args): error_result = 0 good_result = None process(args) if error_condition(): error_result = -1 # flag for an error elif different_error_conditon(): error_result = -2 else: more_processing() if another_error_conditon(): error_result = -3 do_more_work() good_result = "Success!" if error_result != 0: return (False, error_result) else: return (True, good_result) and then call it with: status, msg = joels_function(args) if status == False: print msg # and fail... else: print msg # and now continue... This is how I would write it in Python: def my_function(args): process(args) if error_condition(): raise SomeError("An error occurred") elif different_error_conditon(): raise SomeError("A different error occurred") more_processing() if another_error_conditon(): raise SomeError("Another error occurred") do_more_work() return "Success!" and call it with: try: result = my_function(args) print "Success!!!" except SomeError, msg: print msg # and fail... # and now continue safely here... In the case of Python, calling a function that may raise an exception is no more difficult or unsafe than calling a function that returns a status flag and a result, but writing the function itself is much easier, with fewer places for the programmer to make a mistake. In effect, exceptions allow the Python programmer to concentrate on his actual program, rather than be responsible for building error-handling infrastructure into every function. Python supplies that infrastructure for you, in the form of exceptions. ---- See also: Italian translation at ManutenereLeEccezioni. |
Handling Exceptions
The simplest way to handle exceptions is with a "try-except" block:
If you wanted to examine the exception from code, you could have:
General Error Catching
Sometimes, you want to catch all errors that could possibly be generated, but usually you don't.In most cases, you want to be as specific as possible (CatchWhatYouCanHandle). In the first example above, if you were using a catch-all exception clause and a user presses Ctrl-C, generating a KeyboardInterrupt, you don't want the program to print "divide by zero".
However, there are some situations where it's best to catch all errors.
For example, suppose you are writing an extension module to a web service. You want the error information to output the output web page, and the server to continue to run, if at all possible. But you have no idea what kind of errors you might have put in your code.
In situations like these, you may want to code something like this:
MoinMoin software is a good example of where general error catching is good. If you write MoinMoin extension macros, and trigger an error, MoinMoin will give you a detailed report of your error and the chain of events leading up to it. Python software needs to be able to catch all errors, and deliver them to the recipient of the web page.
Finding Specific Exception Names
Standard exceptions that can be raised are detailed at:
Look to class documentation to find out what exceptions a given class can raise.
See Also:
On this wiki: WritingExceptionClasses, TracebackModule.
For general (non-Python specific) ideas about exceptions, consult ExceptionPatterns.
To Write About...
- Give example of IOError, and interpreting the IOError code.
- Give example of multiple excepts. Handling multiple excepts in one line.
- Show how to use "else" and "finally".
- Show how to continue with a "raise".
Questions
General Error Handling
In the "general error handling" section above, it says to catch all exceptions, you use the following code:
However, it originally was:
Someone pointed out that "except" catches more than just "except Exception, e."
Why is that the case? What is the difference?-- LionKimbro
For now (version 2.3) exception doesn't have to be inherited from Exception. Thus plain 'except:' catches all exceptions, not only system. -- MikeRovner DateTime(2004-01-19T05:49:19Z)
Getting Useful Information from an Exception
So, I've got something like:
1 (a,b,c) = d
...and Python spits back:
ValueError: unpack list of wrong size
...and so, you naturally wonder, "Well, what was in d?"
You know- you can put a print d in there, and that works. But is there a better, more interesting way to get at that information that people know of?
Isn't it better to prevent then to remediate?
> http://www.joelonsoftware.com/items/2003/10/13.html
Joel Spolsky might be a great C++ programmer, and his advice on user interface design is invaluable, but Python is not C++ or Java, and his arguments about exceptions do not hold in Python.
Joel argues:
"They are invisible in the source code. Looking at a block of code, including functions which may or may not throw exceptions, there is no way to see which exceptions might be thrown and from where. This means that even careful code inspection doesn't reveal potential bugs."
I don't quiet get this argument. In a random piece of source code, there is no way to tell whether or not it will fail just by inspection. If you look at:
x = 1 result = myfunction(x)
you can't tell whether or not myfunction will fail at runtime just by inspection, so why should it matter whether it fails by crashing at runtime or fails by raising an exception?
Joel's argument that raising exceptions is just a goto in disguise is partly correct. But so are for loops, while loops, functions and methods! Like those other constructs, exceptions are gotos tamed and put to work for you, instead of wild and dangerous. You can't jump *anywhere*, only highly constrained places.
Joel also writes:
"They create too many possible exit points for a function. To write correct code, you really have to think about every possible code path through your function. Every time you call a function that can raise an exception and don't catch it on the spot, you create opportunities for surprise bugs caused by functions that terminated abruptly, leaving data in an inconsistent state, or other code paths that you didn't think about."
This is a better argument for *careful* use of exceptions, not an argument to avoid them. Or better still, it is an argument for writing code which doesn't has side-effects and implements data transactions. That's a good idea regardless of whether you use exceptions or not.
Joel's concern about multiple exit points is good advice, but it can be taken too far. Consider the following code snippet:
def myfunc(x=None):
- result = "" if x is None:
- result = "No argument given"
- result = "Zero"
elif 0 < x <= 3:
- resutl = "x is between 0 and 3"
- result = "x is more than 3"
There is no benefit in deferring returning value as myfunc does, just for the sake of having a single exit point. "Have a single exit point" is a good heuristic for many functions, but it is pointless make-work for this one. (In fact, it increases, not decreases, the chances of a bug. If you look carefully, myfunc above has such a bug.
Used correctly, exceptions in Python have more advantages than disadvantages. They aren't just for errors either: exceptions can be triggered for exceptional cases (hence the name) without needing to track (and debug) multiple special cases.
Lastly, let me argue against one of Joel's comments:
"A better alternative is to have your functions return error values when things go wrong, and to deal with these explicitly, no matter how verbose it might be. It is true that what should be a simple 3 line program often blossoms to 48 lines when you put in good error checking, but that's life, and papering it over with exceptions does not make your program more robust."
Maybe that holds true for C++. I don't know the language, and wouldn't like to guess. But it doesn't hold true for Python. This is how Joel might write a function as a C programmer:
def joels_function(args):
- error_result = 0 good_result = None process(args) if error_condition():
- error_result = -1 # flag for an error
- error_result = -2
- more_processing() if another_error_conditon():
- error_result = -3
- return (False, error_result)
- return (True, good_result)
and then call it with:
status, msg = joels_function(args) if status == False:
- print msg # and fail...
else:
- print msg # and now continue...
This is how I would write it in Python:
def my_function(args):
- process(args) if error_condition():
raise SomeError("An error occurred")
raise SomeError("A different error occurred")
raise SomeError("Another error occurred")
and call it with:
try:
- result = my_function(args) print "Success!!!"
except SomeError, msg:
- print msg # and fail...
# and now continue safely here...
In the case of Python, calling a function that may raise an exception is no more difficult or unsafe than calling a function that returns a status flag and a result, but writing the function itself is much easier, with fewer places for the programmer to make a mistake.
In effect, exceptions allow the Python programmer to concentrate on his actual program, rather than be responsible for building error-handling infrastructure into every function. Python supplies that infrastructure for you, in the form of exceptions.
See also: Italian translation at ManutenereLeEccezioni.
