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