How does Mr. Martelli's Borg recipe work ?

Bengt Richter bokr at oz.net
Thu Jul 24 04:47:02 CEST 2003


On Wed, 23 Jul 2003 16:40:00 -0600, Steven Taschuk <staschuk at telusplanet.net> wrote:

>Quoth Bengt Richter:
>  [borg vs singleton]
>> How about just
>> 
>>     import zerolengthfile as borginstancename
>> 
>> and using it? E.g., [...]
>
>That would be fine in many cases, I'm sure.
>
>Modules don't do properties (or other descriptor magic), though.
>
Not insurmountable ;-)

====< propmod.py >==========================================
class PropModNames(object):
    def __get__(self, ob, cls=None):
        if ob is None: return self
        return 'Shared names of propmod: %r' % vars(ob).keys()
    def __set__(self, ob, val): raise AttributeError, 'names property is read-only'
    def __delete__(self, ob, val): raise AttributeError, 'names property is read-only'

class SetPropModProp(object):
    def __init__(self): self.name2use = None
    def __get__(self, ob, cls=None):
        if ob is None: return self
        if not self.name2use:
            props = [k for k,v in vars(ob.__class__).items()
                        if not k.startswith('_') and (
                            hasattr(v, '__get__') or hasattr(v, '__set__'))]
            props.sort()
            return 'Properties of propmod: %r' % props
        else:
            return getattr(ob.__class__, self.name2use)
    def __set__(self, ob, nameNprop):
        if isinstance(nameNprop,str): self.name2use = nameNprop
        elif len(nameNprop)==1: delattr(ob.__class__, nameNprop[0]) # (name,) means delete
        else: name, prop = nameNprop; setattr(ob.__class__, name, prop)

class PropMod(object):
    names = PropModNames()
    properties = SetPropModProp() # expects propmod.setprop = name, property or name2use
    def __init__(self): __import__('sys').modules['propmod'] = self
============================================================

===< apm.py >============
import propmod as zz
=========================

The first lines below binds the real propmod module temporarily.
The second line binds the magic propmod locally and makes it available
(by PropMod.__init__ side effect ) for import by anyone else as
an ordinary (looking) "import propmod." (Note what apm.py does).

I thought it cute to make a property that is a kind of gateway to
the class attribute space, so that one can use the .properties attribute
of the propmod module to list, store, retrieve, and delete properties -- as well
as arbitrary class variables...

 >>> import propmod
 >>> propmod = propmod.PropMod()
 >>> propmod.properties
 "Properties of propmod: ['names', 'properties']"
 >>> propmod.names
 'Shared names of propmod: []'
 >>> propmod.x = 123
 >>> propmod.y = 456
 >>> propmod.names
 "Shared names of propmod: ['y', 'x']"
 >>> propmod.properties
 "Properties of propmod: ['names', 'properties']"
 >>> propmod.properties = ('hello', property(lambda self:'Hello properties!'))
 >>> propmod.properties
 "Properties of propmod: ['hello', 'names', 'properties']"
 >>> propmod.hello
 'Hello properties!'
 >>> import apm
 >>> apm.zz.properties
 "Properties of propmod: ['hello', 'names', 'properties']"
 >>> apm.zz.hello
 'Hello properties!'
 >>> apm.zz.z = 'z via apm.zz.z'
 >>> propmod.z
 'z via apm.zz.z'
 >>> apm.zz.names
 "Shared names of propmod: ['y', 'x', 'z']"
 
Not to go on and on, but ...

 >>> apm.zz.properties = ('hello',)
 >>> propmod.properties
 "Properties of propmod: ['names', 'properties']"
 >>> propmod.properties = 'names'
 >>> propmod.properties
 <propmod.PropModNames object at 0x007E01F0>
 >>> propmod.properties = ''
 >>> propmod.properties
 "Properties of propmod: ['names', 'properties']"
 >>> propmod.properties = ('classvar', 'classvar value')
 >>> apm.zz.properties
 "Properties of propmod: ['names', 'properties']"
 >>> apm.zz.classvar
 'classvar value'
 >>> apm.zz.__class__
 <class 'propmod.PropMod'>
 >>> apm.zz.__class__.__dict__.keys()
 ['__module__', 'names', '__dict__', 'classvar', '__weakref__', 'properties', '__init__', '__doc__']
 >>> apm.zz.__class__.__dict__['classvar']
 'classvar value'
 >>> apm.zz.classvar = 'obj attr'
 >>> propmod.names
 "Shared names of propmod: ['y', 'x', 'z', 'classvar']"
 >>> propmod.classvar
 'obj attr'
 >>> del propmod.classvar
 >>> propmod.classvar
 'classvar value'

Regards,
Bengt Richter




More information about the Python-list mailing list