variables in a class - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: General (https://python-forum.io/forum-1.html) +--- Forum: News and Discussions (https://python-forum.io/forum-31.html) +--- Thread: variables in a class (/thread-22111.html) |
variables in a class - Skaperen - Oct-30-2019 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 RE: variables in a class - Larz60+ - Oct-30-2019 Don't know if this is of any value to you, but I wrote the following earlier this year, for dictionary manipulation, and it works well: import os class CreateDict: """ CreateDict.py - Contains methods to simplify node and cell creation within a dictionary Usage: The best way to learn what can be done is to examine the testit function included in this module. new_dict(dictname) - Creates a new dictionary instance with the name contained in dictname add_node(parent, nodename) - Creates a new node (nested dictionary) named in nodename, in parent dictionary. add_cell(nodename, cellname, value) - Creates a leaf node within node named in nodename, with a cell name of cellname, and value of value. display_dict(dictname) - Recursively displays a nested dictionary. Requirements: Python standard library: os Author: Larz60+ -- May 2019. """ def __init__(self): os.chdir(os.path.abspath(os.path.dirname(__file__))) def new_dict(self, dictname): setattr(self, dictname, {}) def add_node(self, parent, nodename): node = parent[nodename] = {} return node def add_cell(self, nodename, cellname, value): cell = nodename[cellname] = value return cell def display_dict(self, dictname, level=0): indent = " " * (4 * level) for key, value in dictname.items(): if isinstance(value, dict): print(f'\n{indent}{key}') level += 1 self.display_dict(value, level) else: print(f'{indent}{key}: {value}') if level > 0: level -= 1 def testit(): # instantiate class cd = CreateDict() # create new dictionary named CityList cd.new_dict('CityList') # add node Boston boston = cd.add_node(cd.CityList, 'Boston') # add sub node Resturants bos_resturants = cd.add_node(boston, 'Resturants') # Add subnode 'Spoke Wine Bar' to parent bos_resturants spoke = cd.add_node(bos_resturants, 'Spoke Wine Bar') cd.add_cell(spoke, 'Addr1', '89 Holland St') cd.add_cell(spoke, 'City', 'Sommerville') cd.add_cell(spoke, 'Addr1', '02144') cd.add_cell(spoke, 'Phone', '617-718-9463') # Add subnode 'Highland Kitchen' to parent bos_resturants highland = cd.add_node(bos_resturants, 'Highland Kitchen') cd.add_cell(highland, 'Addr1', '150 Highland Ave') cd.add_cell(highland, 'City', 'Sommerville') cd.add_cell(highland, 'ZipCode', '02144') cd.add_cell(highland, 'Phone', '617-625-1131') # display dictionary print(f'\nCityList Dictionary') cd.display_dict(cd.CityList) print(f'\nraw data: {cd.CityList}') if __name__ == '__main__': testit() RE: variables in a class - Skaperen - Oct-30-2019 that looks like an implementation just based on calling methods to do everything. i don't want to do things that way. i want to have things be usable on the LHS of an = operator, too, while still being commonly shared in functions/methods being called with the caller that is calling it. and i want to be able to do this many levels deep (so this may mean passing a reference to the class or object all along the way). RE: variables in a class - Skaperen - Oct-31-2019 what i have been doing is importing or inserting that adict class and defining a few instances of it, as needed. then functions and methods can use it as a global or use one passed to it as an argument or keyword argument. side effects galore! |