Generate a new object each time a name is imported
michele.simionato at gmail.com
Fri Aug 7 06:54:25 CEST 2009
On Aug 2, 1:18 pm, Paul Rubin <http://phr...@NOSPAM.invalid> wrote:
> Peter Otten <__pete... at web.de> writes:
> > >>> import sys
> > >>> sys.modules["yadda"] = A()
> OMG.... wow. I bow to you. But I'm not sure whether that's bowing in
> awe or in terror.
I had to play this kind of tricks on our production code, not so long
ago. Not that I am pride of it, but it was the lesser evil to cope
with a wrong design. The scenario: a large legacy code base
based on the idea of using a Python module to keep configuration
parameters. The idea is fine as long as the parameters are
immutable, but in our case the parameters could be changed.
In theory the parameters should have been set only once,
however in practice this was not guaranteed: every piece
of code could change the parameters at some moment, and things
could get "interesting" to debug.
Throwing away the configuration system was not an option, because
it would have involved changing hundreds of modules, so I set out
for a compromise: the parameters are still mutable, but they
can be changed only once. This was implemented by replacing
the module with a configuration object using custom
descriptors. Here is the code:
$ echo config.py
def __init__(self, default):
self.default = self.value = default
self.already_set = False
def __get__(self, obj, objcls):
def __set__(self, obj, value):
if value != self.value and self.already_set:
raise TypeError('You cannot set twice a write-once
self.value = value
self.already_set = True
"A singleton to be used as a module"
parameter = WriteOnce(0)
sys.modules['config'] = Config()
The usage is
>>> import config
>>> config.parameter = 42
>>> config.parameter = 43
Traceback (most recent call last):
TypeError: You cannot set twice a write-once attribute!
Just to say that there are use cases where replacing modules with
objects may have sense.
Still, a better design would just have passed immutable configuration
(changing the configuration would mean to create a new object).
Unfortunately there are still a lot a people without a functional
More information about the Python-list