Q's on my first python script
Steven D'Aprano
steve at REMOVE-THIS-cybersource.com.au
Sun May 10 11:56:00 EDT 2009
On Sun, 10 May 2009 12:52:21 +0000, kj wrote:
> 1. The name of the BadArgument exception class defined in the script
> does not seem to me sufficiently specific. If one were to import the
> script in order to reuse its wkday_abbrev function, I'd like this
> exception's name to be more unequivocally tied to this script. What
> I'm looking for is something like a "namespace" for this script.
> What's the pythonic way to construct a namespace?
You already have one. The module you have created is a namespace. If your
script is called "myscript.py", then to use it elsewhere you would do:
import myscript
raise myscript.BadArgument
> 2. In some python modules I've seen the idiom
>
> if __name__ == "__main__":
> # run some tests here
>
> I'd like to set up tests for this script, mostly to ensure that it
> handles the error cases properly, but I'm alread using the idiom
> above to actually run the script under normal operation. What's the
> typical python idiom for running tests on a *script* (as opposed to a
> module that is normally not supposed to be run directly)?
I sometimes give my scripts an option -t or --self-test, and then run
tests if that option is passed on the command line.
Alternatively, put your tests in another module, say, myscript_tests.py,
and then just run that when you want to test myscript.
> 3. Still on the subject of testing, how does one capture in a
> variable the output that would normally have gone to stdout or
> stderr?
Normally you would write the function to *return* the result, rather than
*print* the result. If all output goes through the function return
mechanism, then it's easy to capture: x = func().
However, for cases where the function does print directly, you can
redefine stdout and strerr to be any file-like object, so you can do
something like this:
# untested
import sys
import cStringIO
save_stdout, save_stderr = sys.stdout, sys.stderr
c1 = cStringIO.StringIO()
c2 = cStringIO.StringIO()
try:
sys.stdout = c1
sys.stderr = c2
result = func(*args, **kwargs) # normally prints some stuff
finally:
# restore standard files
sys.stdout = save_stdout
sys.stderr = save_stderr
captured_from_stdout = c1.getvalue()
captured_from_stderr = c2.getvalue()
> 4. What's the python way to emit warnings? (The script below should
> warn the user that arguments after the first one are ignored.)
import warnings
warnings.warn("The end of the world is coming!")
> 5. The variable wd is meant to be "global" to the script. In other
> languages I've programmed in I've seen some typographic convention
> used for the name of such variables (e.g. all caps) to signal this
> widened scope. Does python have such a convention?
As a general rule, it's best to avoid globals variables as much as
possible.
One convention I occasionally use is to prefix global variables with a
lowercase g. And then ruthlessly refactor my code until any variable
starting with a lowercase g is removed :)
--
Steven
More information about the Python-list
mailing list