tobiah wrote:
I am making a web app, made up of many modules
that all need access to some important data, like
the current session data, cookies, navigation history,
post/get variables, etc.
I decided to go with the 'Borg' idea, by assigning the
__dict__ of an object to a class variable so that each
instantiation of the Borg() would share the same data.
That way I can either pass the Borg around, or just
Borg() it if I need it in some obscure place.
Then I read an argument that it usually makes more sense
to just have a module with the data and functions that
I need, which all the other modules can simply import.
Since I only need one instance, I could just stuff data
and call 'methods' on this module, probably without even
changing existing syntax.
Are there any arguments as to which method is better?
I would recommend a module over a Borg class simply because it's less
of a hack.
One thing that I never liked about using modules as classes was the
constant need to use the global statement when rebinding any module
level variables. For that reason, if there was a lot of rebinding, I
would rewrite the module as a singleton class. That had its own
problems; most significantly, it was a thorn in my side for
initializing things in the right order. (My current project used lots
of circular imports which made things a lot worse.)
I finally lost my patience and decided to pull that thorn out by
converting the singletons back to modules. That's when I came up with
this little decorator that obviates the need to use global statements,
plus it lets the module look and mostly act like a class.
def modmethod(func):
class modproxy(object):
__getattribute__ = func.func_globals.__getitem__
__setattr__ = func.func_globals.__setitem__
self = modproxy()
def call_with_method(*args,**kwargs):
return func(self,*args,**kwargs)
call_with_method.func_name = func.func_name
return call_with_method
This decorator means the function will get called with the module
(actually a proxy) as the first argument. That way, you can access
module-level variable exactly like you would access instance variables
in a class, i.e., via self.
I was able to convert all my singletons to modules simply by dedenting
one level, and prefixing all the methods with @modmethod. This worked
so sweetly it this is now my slam dunk recommendation for implementing
a "global singleton" class.
Carl Banks