Oct-30-2019, 07:48 AM
a while back, someone suggested to use variables in a class to share a namespace between a function or method. i am wondering if this class can do the job.
class adict(dict): '''Class that is like a dictionary with items usable like attributes. #--------------------------------------------------------------- # purpose class that is a dictionary with items usable # like attributes so code can look like: # obj1.foo = obj2.bar # instead of: # obj1['foo'] = obj2['bar'] # although the latter may also be used # # warning this class will fail in cases where keys # have values the same as existing methods # # init usage object = adict(dictionary) # object = adict(dictionary,key=value...) # object = adict(key=value...) # # methods _copy, _find, _sans plus all dict methods # # attr usage object.name # # dict usage object[key] # # note attribute usage is like string keys that are # limited to what can be a valid identifier while # dictionary usage can use any hashable value as # a key #--------------------------------------------------------------- ''' def __init__(self,*args,**opts): arn = 0 for arg in args: arn += 1 if isinstance(arg,(adict,dict)): self.update(arg) elif arg and isinstance(arg,(list,tuple)): an = -1 for ar in arg: an += 1 if isinstance(ar,(list,tuple)) and len(ar)==2: self[ar[0]] = ar[1] else: raise TypeError('not a 2-sequence at ['+str(an)+'] of argument '+str(arn)) else: raise TypeError('argument '+str(arn)+' is not a sequence') if opts: if isinstance(opts,(adict,dict)): self.update(opts) else: raise TypeError('options ('+repr(opts)+') is not a dictionary') def __delattr__(self,key): """Delete any attribute or list of keys.""" if isinstance(key,list): for k in key: del self[k] else: del self[key] return self def __getattr__(self,key): """Get any attribute.""" return self[key] def __setattr__(self,key,value): """Set any attribute.""" self[key] = value return self def _copy(self): """Shallow copy.""" return adict(self) def _find(self,*args): """Find a value from a key or list of keys or return default.""" keys = args[0] if not isinstance(keys,list): keys = [keys] for key in keys: if key in self: return self[key] return None if len(args)<2 else args[1] def _sans(self,keys): """Copy without a key or list of keys.""" new=adict(self) if not isinstance(keys,list): keys = [keys] for key in keys: new.pop(key,None) return new