namespace dictionaries ok?

Bengt Richter bokr at oz.net
Tue Oct 25 16:55:52 EDT 2005


On Tue, 25 Oct 2005 16:20:21 GMT, Ron Adam <rrr at ronadam.com> wrote:

>Duncan Booth wrote:
>> Ron Adam wrote:
>> 
>>>James Stroud wrote:
>>>
>>>>Here it goes with a little less overhead:
>>>>
>>>>
>> 
>> <example snipped>
>> 
>>>But it's not a dictionary anymore so you can't use it in the same places 
>>>you would use a dictionary.
>>>
>>>       foo(**n)
>>>
>>>Would raise an error.
>>>
>>>So I couldn't do:
>>>
>>>    def foo(**kwds):
>>>       kwds = namespace(kwds)
>>>       kwds.bob = 3
>>>       kwds.alice = 5
>>>       ...
>>>       bar(**kwds)     #<--- do something with changed items
>>>
>> 
>> I agree with Steven D'Aprano's reply, but if you are set on it you could 
>> try this:
>> 
>> 
>>>>>class namespace(dict):
>> 
>> 	def __init__(self, *args, **kw):
>> 	    dict.__init__(self, *args, **kw)
>> 	    self.__dict__ = self
>> 
>> 	    
>> 
>>>>>n = namespace({'bob':1, 'carol':2, 'ted':3, 'alice':4})
>>>>>n.bob
>> 
>> 1
>> 
>>>>>n.bob = 3
>>>>>n['bob']
>> 
>> 3
>> 
>> The big problem of course with this sort of approach is that you cannot 
>> then safely use any of the methods of the underlying dict as they could be 
>> masked by values.
>> 
>> P.S. James, *please* could you avoid top-quoting.
>
>Or worse, the dictionary would become not functional depending on what 
>methods were masked.
>
>
>And this approach reverses that, The dict values will be masked by the 
>methods, so the values can't effect the dictionary methods.  But those 
>specific values are only retrievable with the standard dictionary notation.
>
>     class namespace(dict):
>         __getattr__ = dict.__getitem__
>         __setattr__ = dict.__setitem__
>         __delattr__ = dict.__delitem__
>
>     n = namespace()
>     n.__getattr__ = 'yes'    # doesn't mask __getattr__ method.
>
>     print n['__getattr__']   -> 'yes'
>
>The value is there and __getattr__() still works.  But n.__getattr__ 
>returns the method not the value.
>
>So is there a way to keep the functionality without loosing the methods?
>
>
>BTW, I agree with Steven concerning data structures.  This really isn't 
>a substitute for a data structure.  Many keys will not work with this.
>
>     n.my name = 'Ron'
>     n.(1,2) = 25
>     n.John's = [ ... ]
>
>The use case I'm thinking of is not as a shortcut for data structures, 
>but instead, as a way to keep names as names, and maintaining those 
>names in a group.  Thus the namespace association.
>
>    def foo(**kwds):
>       kwds = namespace(kwds)
>       print kwds.name
>       print kwds.value
>       ...
>
>    name = 'ron'
>    value = 25
>    foo( name=name, position=position )
>
Just had the thought that if you want to add bindings on the fly modifying the
original object, you could use the __call__ method, e.g.,

 >>> class NameSpace(dict):
 ...     __getattr__ = dict.__getitem__
 ...     __setattr__ = dict.__setitem__
 ...     __delattr__ = dict.__delitem__
 ...     def __call__(self, **upd):
 ...         self.update(upd)
 ...         return self
 ...
 >>> def show(x): print '-- showing %r'%x; return x
 ...
 >>> ns = NameSpace(initial=1)
 >>> show(ns)
 -- showing {'initial': 1}
 {'initial': 1}

And updating with a second keyword on the fly:

 >>> show(show(ns)(second=2))
 -- showing {'initial': 1}
 -- showing {'second': 2, 'initial': 1}
 {'second': 2, 'initial': 1}

FWIW ;-)

Regards,
Bengt Richter



More information about the Python-list mailing list