Refactoring Dilemma

Carl Banks pavlovevidence at gmail.com
Mon Sep 11 01:44:16 CEST 2006


George Sakkis wrote:
> Kamilche wrote:
> > '''
> > I'm in the middle of a refactoring dilemma.
> > I have several singletons that I'm turning into modules, for ease of
> > access.
> > The usual method is noted as 'Module 1' below.
> > The new method is noted as 'Module 2'.
> > Is there any reason NOT to do this that I may be unaware of?
> > It's easier than remembering to declare global variables at the top of
> > the function.
> > '''
> >
> > # ----------- Module 1.py ------------
> > # Normal module processing
> > var = 0
> >
> > def MyRoutine():
> >     global var
> >     var = 1
> >
> > MyRoutine()
> > print var
> >
> >
> > # ----------- Module 2.py ------------
> > # 'Self' module processing
> > import sys
> > var = 0
> > self = sys.modules[__name__]
> >
> > def MyRoutine():
> >     self.var = 1
> >
> > MyRoutine()
> > print var
>
>
> What's wrong with
> <code>
> def MyRoutine():
>      return 1
>
> var = MyRoutine()
> </code>
> ?


Kamilche simplified things in his example that obscured the main use
case.  Short story is, var is considered a state of the module, and
MyRoutine() is designed to be called from outside the module to modify
the state.  Your suggestion can only modify the state of the module
from within, so it won't do.

More detailed discussion:

A common piece of advice when people ask "how can I implement a
singleton in Python" is to use a module.  A module, after all, is a
singleton object.

But there's a big problem using a module as a singleton: you need to
use then global statement to rebind module-level variables.  Which
means that if you want your module to have lots of modifyable state,
most likely you'll have to use a bunch global statements.  And that's a
major pain in the neck when you have to do it a lot and in many
functions.

In these cases, it would be nice if a module could access its own state
in the same way that an instance does, that is, as an attribute.  My
approach of using a decorator to pass in a module proxy, and Kamilche's
approach  of binding the module object to self, both accomplish this.
Internally, the module behaves very much like a class instance.
Functions in the module act almost exactly like bound methods, and
module-level variables act like instance attributes.  The difference
between writing a module and a singleton class thus becomes mostly a
matter of indentation.

In fact, when I made a major switch from using singleton classes to
modules, I was able to change it by dedenting once, and pasting a
@modmethod decoration above each method, with very few other changes.

Carl Banks

Carl Banks




More information about the Python-list mailing list