Bengt Richter wrote: > On Tue, 25 Oct 2005 16:20:21 GMT, Ron Adam <[EMAIL PROTECTED]> wrote:
>>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 Getting better! ;-) That (or something similar) might avoid copying the whole thing in some situations, which is something I am concerned about. But how to change a dict to a namespace without copying the contents item by item? I'm not sure where or if this is going anywhere. It may tie back into the properties groups example (see below) I posted earlier and keep finding improvements for. ;-) cheers, Ron """ GPobject.py Grouped Properties Object: This need has presented itself while programming Tkinter applications where a *LOT* of keywords are used. I think property groups would also be good for general interface building. The external view is of a single cohesive object, while the internal mechanism keeps the attributes grouped so they can be forwarded easily as **kwds. class foo(GPobject): def __init__(self): self.properties(name, item_1, item_2, ... item_n) def getter(): ... def setter(): ... def remover(): ... self.name.doc( __doc__ string ) self.name.get = getter self.name.set = setter self.name.remove = remover * The properties() method can also accept a dictionary. This will set both the names and the values at the same time. self.properties(name, dictionary) class myclass(GPobject): def __init__(self, **kwds): self.properties('kwds', **kwds) * group.setup() allows easy initiation of get, set, remove, and doc group settings in one step. self.properties( name, *members ) self.name.setup( get=myget, set='set', del='del', doc='a property group' ) * Using string flags to indicate default values lets you shorten the expression further. self.properties( name, *members ) self.name.setup( myget, 'set', 'del', 'a property group') The following is only somewhat tested... but it seems to work. """ class GPdict(dict): doc = "a property group" def doc(self, docstring): self.__doc__ = docstring def get(self, item): return self[item] def set(self, item, value): self[item] = value def remove(self, item): del self[item] def setup( self, fget='get', fset='set', fdel='del', doc=doc ): if fget != 'get': self.get = fget if fset != 'set': self.set = fset if fdel != 'del': self.remove = fdel self.__doc__ = doc # Some useful common alternate methods to # replace get, set and remove. def readonly(self, *args): raise AttributeError, 'read only property' def setonce(self, item, value): if self[item] is None: self[item] = value else: raise AttributeError, 'set once property' def nonremovable(self, *args): raise AttributeError, 'non removable property' class GPobject(object): """ an object that can use grouped properties """ __properties__ = {} def __new__(cls, *args, **kwds): cls.__properties__ = {} return object.__new__(cls, *args, **kwds) def properties(self, *args, **kwds): dct = GPdict() for i in args[1:]: dct.setdefault(i,None) dct.update(kwds) self.__properties__[args[0]] = dct self.__dict__[args[0]] = dct def __getattr__(self, name): for dct in self.__properties__: if name in self.__properties__[dct]: return self.__properties__[dct].get(name) return self.__dict__[name] def __setattr__(self, name, value): notprop = True for dct in self.__properties__: if name in self.__properties__[dct]: self.__properties__[dct].set(name,value) notprop = False if notprop: self.__dict__[name] = value def __delattr__(self, name): for dct in self.__properties__: if name in self.__properties__[dct]: self.__properties__[dct].remove(name) return del self.__dict__[name] ================= ### Properties as keyword sorter example, ### (sort to groups, not ordered sort) class sorter(GPobject): text_group = str.split('text fill font') line_group = str.split('line fill arrows') def __init__( self, text=None, fill=None, line=None, arrows=None, font=None ): self.properties('_text', *self.text_group) self.properties('_line', *self.line_group) self.text = text self.fill = fill self.line = line self.arrows = arrows self.font = font s = sorter(text='hello', fill='black', line='solid', arrows='both') print 's._text =', s._text print 's._line =', s._line print s.__properties__ -- http://mail.python.org/mailman/listinfo/python-list