Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
variables in a class
#1
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
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#2
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()
Reply
#3
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).
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#4
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!
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020