Refactoring Dilemma

Carl Banks pavlovevidence at gmail.com
Mon Sep 11 04:37:17 CEST 2006


George Sakkis wrote:
> Carl Banks wrote:
> > 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
>
> This looks quite hackish, both the implementation and the usage;

Once again, the function MyRoutine is intended to be called from
another module.  The usage I have here is just an example demonstrating
that var is in the module's dict.  Please keep this in mind when
criticizing usage.  The intended usage would be something like this
(from another module):

from xxx import yyy
yyy.MyRoutine()

As far as the caller is concerned, yyy could be a module using globals,
a module with this "hack", or a class instance, or something else.  It
doesn't matter; usage is the same in all three cases.

As for the implementation...

> most
> people would get confused when they didn't find var's assignment at
> global scope. I prefer the the simple global statements if they aren't
> that many, otherwise the assignment of the module to self is also fine.

For ordinary modules that might have one or two serial number counters
or debug flags or whatnot, I agree.  For modules that have lots of
state and act more like class instances than modules, the massive
amounts of globals are ugly and error prone.  In that case you should
either use a regular class, or tolerate the "hack"; don't use a bunch
of globals.

I think a simple comment at the top could take care of any confusion
about what's happening.  Since it mimics how a class works, it won't be
anything completely new.

YMMV.

Carl Banks




More information about the Python-list mailing list