Style for modules with lots of constants
Paul McGuire
ptmcg at austin.rr._bogus_.com
Wed Nov 1 11:26:31 EST 2006
"Neil Cerutti" <horpner at yahoo.com> wrote in message
news:slrnekhbru.1as.horpner at FIAD06.norwich.edu...
> The Glk API (which I'm implementing in native Python code)
> defines 120 or so constants that users must use. The constants
> already have fairly long names, e.g., gestalt_Version,
> evtype_Timer, keycode_PageDown.
>
> Calls to Glk functions are thus ugly and tedious.
>
> scriptref = glk.fileref_create_by_prompt(
> glk.fileusage_Transcript | glk.fileusage_TextMode,
> glk.filemode_WriteAppend, 0)
>
> Please give me some good style advice for this situation.
>
> I know some modules are designed to be used as 'from XXX import
> *'. Since the Glk API is heavily influenced by its inception in
> C this might not be a huge problem. All the functions in the API
> have glk_ prepended, since C has no namespaces. I think it makes
> sense to stick the glk_'s back on the functions and instruct
> users to 'from Glk import *', but I know it doesn't conform with
> Python practice, and Python has plenty of modules that were
> originally designed in C, but don't insist on polluting the
> global namespace.
>
Neil -
I recently had to add some new constants to pyparsing, representing LEFT and
RIGHT, but I didn't want to define such generic and
likely-to-collide-with-user-code variable names.
I settled on defining my own flavor of the Bag class, which I named
Constants since it is there specifically to define constants (although it
does nothing to enforce the "constant-ness" of the values).
class Constants(object)
pass
(I guess value immutability could probably be implemented using clever
implementations of __setattr__ and such, but is it really worth the
bother?).
Then I defined the context for my LEFT and RIGHT constants, which are being
created to specify operator associativity, and then my constant fields as
attributes of that object:
opAssoc = Constants(object)
opAssoc.RIGHT = 0
opAssoc.LEFT = 1
In client modules (that is, those that import your library) that don't like
"from pyparsing import *", they can just add opAssoc to the list of imported
names (as in "from pyparsing import opAssoc"), and all of the related
constant definitions come along for the ride.
In your example, this would look something like:
fileusage = Constants()
fileusage.Transcript = 1
fileusage.TextMode = 2
filemode = Constants()
filemode.Read = 1
filemode.Write = 2
filemode.Append = 4
filemode.WriteAppend = filemode.Write | filemode.Append
and so on. In the client modules they would simply enter "from glk import
fileusage, filemode". Or if they just "import glk", the references to the
constants look like "glk.filemode.Append", "flk.fileusage.TextMode", etc.,
and those garish and unsightly '_' separators are reduced to svelte little
'.'s.
I think this is a reasonable compromise in avoiding namespace pollution,
without inflicting unseemly text entry overhead on your module clients.
-- Paul
More information about the Python-list
mailing list