Python and Exceptions
Coming from a Java background, I like it when I was warned that I was not catching an exception, without having to read the documentation. And if I did read the documentation about a method, the exception thrown was shown right in the documentation's method signature.
With Python I have to often read through a paragraph of t开发者_开发问答ext in the documentation, to find one sentence stating what exception will be thrown.
Also, I was using a third party library in Python today, http://packages.python.org/kombu/reference/kombu.connection.html and this infuriates me. There is no standard documentation format? I was using the channel method ( http://packages.python.org/kombu/reference/kombu.connection.html#kombu.connection.BrokerConnection.channel ) and it doesnt even state that it throws an exception. I had to find this through trial and error.
Am I missing something obvious here, or are exceptions treated as an afterthought in Python and its documentation.
We love exceptions. They're a pretty important language feature. Good documentation will generally state what exceptions will be thrown in which cases, and personally I found most documentation to be good in this regard. Of course there's always some percentage of documentation that isn't good. Either way, if you're looking for an explicit free-standing list per function, you're out of luck. Nobody knows this except the programmers working on the code.
Reading a paragraph doesn't sound too bad to me, especially since the information that paragraph is usually very important either way. And then there's <Ctrl+F>raises<Enter>
...
There is no standard documentation format?
There's Sphinx, which is used by many projects (including docs.python.org
so you already know it; and also including the project you linked to although it uses a different optical style). Of course nobody can force every project to use it, just like you can't force them to use the standard coding style. But honestly, I think all projects I've used so far except two (PyGame and LEPL) used Sphinx. This may be because I have to use relatively few thanks to the extensive standard library, but still.
I like it when I was warned that I was not catching an exception
Why? At a wild guess, 60% of the exceptions beginners get is because they didn't code properly, not because of some exceptional enviromental state that needs to be handled. TypeError
and ImportError
, for instance, simply don't occur in a bug-free well-written program (save metaprogramming and sections that require extreme dynamism).
In general, if you want the compiler to tell you things about your code you didn't already knew, you're using the wrong language. Python is dynamic, you test instead of analyzing statically. Deal with it.
Bruce Eckel discusses Java checked exceptions vs Python exceptions at length. Key quote:
When I started using Python, all the exceptions appeared, none were accidentally "disappeared." If you want to catch an exception, you can, but you aren't forced to write reams of code all the time just to be passing the exceptions around. They go up to where you want to catch them, or they go all the way out if you forget (and thus they remind you) but they don't vanish, which is the worst of all possible cases. I now believe that checked exceptions encourage people to make them vanish. Plus they make much less readable code.
It's worth reading the whole article.
Regarding documentation I say that yes, some documentation is bad.
Python does not have the same requirements for declaring exceptions that Java does. Most languages don't. For that matter, Java will often throw exceptions which are not immediately declared (NullPointerException
anyone?). It is polite to document exceptions in all languages, but in a world where we can't even guarantee that a public method will even be documented at all, is this really that surprising?
Looking at the library you're using, it seems like you needed to instantiate a Transport object (the thing which really raised the Exception) does have a list of exceptions which are thrown. That's the real object throwing the exceptions, not the BrokerConnection.
Do you know about the traceback module? It might help you track down these issues in the future.
I think it's a matter of perspective. The Java system has it's own faults. For example, most of the time in Java I found that I was just writing a printStackTrace. Sometimes, I needed to do something more complicated. For example, the system needed to print error messages to the user that was connected via telnet. Again, there was a huge amount of boilerplate.
This is why liked that python has it's way of letting you define a single function to catch all uncaught exceptions: sys.excepthook
. Granted, that comes with it's own set of problems, but I like that the functionality is there if I need it.
While I can't vouch for your experience with the 3rd party library you referred to, I'd say that at least documentation of the Exceptions is expected. Take the built-in smtplib for example. The Exceptions that can be throw are explained, and the methods include information about which ones they'll throw and why.
As far as knowing ahead of time what exceptions could be thrown, whether you're failing to account for one, etc - you may find some code introspection in an IDE that will give you what you're after.
In my experience, exceptions are either things you know know ahead of time are coming up because you've got uncontrollable setup conditions (dealing with user input, etc) or you operate using methods that encapsulate the behavior in a way that rules them out. For example, in Python, if you were working with an Object that should have a given attribute, but you're uncertain that you can guarantee that it will have this attribute, instead of making a call to Object.method()
you do this instead:
# getattr uses the arguments (object, 'attribute', default)
toCall = getattr(MyInstance, 'methodName', None)
if toCall is not None:
toCall(args)
# or if you prefer
if toCall is None:
myDialogClass.NotifyUser('Object does not contain necessary method.')
When working with collections like dictionaries it's even easier:
nums = dict((i, i) for i in range(30))
# Here the .get() method takes the form (key, default)
# No such thing as a KeyError
nums.get('50', None)
So, generally, when you discuss python programming, the idea is not that you need to make sure every exception is accounted for. Quite the opposite. Account for the ones you must, but program using idioms that minimize the number of them you have to deal with.
精彩评论