Kindly take note.
Please do not do any of the following when
writing Python software. I have done all of these things at one time or another, FWIW:
- Use
from foo.bar import *. You might know what foo.bar's __all__ is, but I don't, and I bet other people don't either. Don't make us look it up. How much time are you actually saving? You can be sure it's outweighed by the time you make other people waste by tracking down some name that isn't findable in the file itself.
- Write library modules that have import-time side-effects like a monkeypatch, or something that puts objects into a registry defined in another module. This makes it not-a-library. This makes it an application.
- Use the Python warnings module to emit deprecation warnings that don't tell me how to change the code to do what I'm trying to do in what must of course be a newer, better way.
- Cause warnings to be emitted when I start an app that uses your library because you're still using your own older APIs, which you've deprecated. That puts the K in kwality.
- Use "@" decorator syntax gratiutiously. I'm glad you know how to use it, and I'm suitably impressed. But pretty soon you're going to realize how ridiculous what you're doing is.
- Hide real exceptions and raise your own that lose information in library code. I'm glad you thought about that case, but now I just need to comment out your except clause to figure out what the real problem is.
Please do not do any of the following when
writing software in any language (I have also done each of these):
- Write a 1k test module for 40K worth of code, at least if you want other people to use your code. While I commend even one test, it's just not enough. On an average projects (at least the ones I let other people use or even see), I actually have more test code than actual code. And I still don't test everything.
- Leave huge chunks of commented-out logic laying around. Version control has been around a long time now.
- Print anything to the console in something that other people use as a library. This is just rude.
- Factor code in such a way that something completely general depends on importing something completely unrelated because you couldn't be bothered to factor out the logic into something that both pieces could depend on.
- Cargo-cult code. Nobody is perfect. Stop for a second and make sure you're not aping something that's even worse than what you might come up with if you started from scratch.
Thank you.
I think few people know that "raise" (with no arguments) re-raises the exception without breaking the traceback. I'm constantly encountering people who are surprised by this (rather important) feature.
Augmenting an exception is rather hard, but generally better. You have to do something like "exc.args = exc.args + ('extra info',)", but even more if you want it to be nicely formatted, and it doesn't necessary work with all exceptions.
You can technically keep the traceback and change the exception, with the even more obscure three-argument form of raise. But that can be kind of weird to look at, seeing "raise FooError" in the traceback, but not actually getting a FooError.