Python Forum
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!