Refactoring Dilemma

Carl Banks pavlovevidence at gmail.com
Sun Sep 10 18:50:06 EDT 2006


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

I don't see any major problem with it.  In fact, I think it's a very
good idea to do this, rather than use global statements, when using
module as a singleton class.

I recently made the same transition myself, though I solved it a bit
differently.  I used a decorator to pass the module as the first
argument (actually it passes a proxy to module's global dict, since the
module itself isn't accesible from the function object).

def modmethod(func):
    class modproxy(object):
        __getattribute__ = func.func_globals.__getitem__
        __setattr__ = func.func_globals.__setitem__
    self = modproxy()
    def call_with_module(*args,**kwargs):
        return func(self,*args,**kwargs)
    call_with_module.func_name = func.func_name
    return call_with_module

@modmethod
def MyRoutine(self):
    self.var = 1

MyRoutine()
print var

One problem with my decorator is it makes stack traces a little
bloated. (Also attribute errors are raised as KeyError, but that's
easily fixable.)  Other than that, I've been running it for awhile
without any problems.  I doubt your approach would have many problems,
either. 


Carl Banks




More information about the Python-list mailing list