Search code examples
pythonclassnestedstructureidl-programming-language

How to handle data in python similar to IDL structures?


So I am converting some code from IDL to python. In the IDL there are about 50 variables held in a structure of structures;

values = { struct1: {a = 1, b = 2}, struct2: {a = 3, b = 4} ... etc }

The data can be accessed as follows:

print, values.struct1.a
# 1

Is there an easy way to do this in python where I can still have methods in the class values that act on the inner classes? For instance, having one setValues method that can change values in struct1 or struct2? I was hoping for something like this:

class values:
    def __init__(self):
         self.struct1 = self.struct1()
         self.struct2 = self.struct2()

    class struct1:
         def __init__(self):
             self.a = 1
             self.b = 2
    class struct2: 
         def __init__(self):
             self.c = 3
             self.d = 4

    def setValues(self, **kwargs):
        for key,value in kwargs.items():
             setattr(self, key, value)
        return

Where I could execute the following code:

st = values()
st.setValue(struct1.a = 2.0, struct2.a = 5.0)
print, st.struct1.a , st.struct2.a
# 2.0
# 5.0

but I get the following error:

AttributeError: values instance has no attribute 'struct1'

I am pretty new to python and was curious if anyone had some insight on a better way to produce a nested class and have methods that can act on all nests.


Solution

  • Having the code:

    class values:
    
        class struct1:
             def __init__(self):
                 self.a = 1
                 self.b = 2
    
        class struct2: 
             def __init__(self):
                 self.c = 3
                 self.d = 4
    
        def __init__(self):
             self.struct1 = self.struct1()
             self.struct2 = self.struct2()
    
        def setValue(self, **kwargs):
            for key, value in kwargs.items():
                try:
                    getattr(self.struct1, key)
                except AttributeError:
                    # self.struct1 don't have any attribute which name is the value of 'key'.
                    pass
                else:
                    setattr(self.struct1, key, value)
    
                try:
                    getattr(self.struct2, key)
                except AttributeError:
                    # self.struct2 don't have any attribute which name is the value of 'key'.
                    pass
                else:
                    setattr(self.struct2, key, value)
    

    You can:

    >>> st = values()
    >>> st.struct1.a = 10
    >>> st.struct2.c = 20
    >>> print(st.struct1.a)
    >>> 10
    >>> print(st.struct2.c)
    >>> 20
    >>> st.setValue(b=20, a=100, d=50, c=60)
    >>> print(st.struct1.a)
    >>> print(st.struct1.b)
    >>> print(st.struct2.c)
    >>> print(st.struct2.d)
    >>> 100
    >>> 20
    >>> 60
    >>> 50
    

    EDIT: In your original question you had __init instead __init__ and:

    self.struct1 = self.struct1()
    self.struct1 = self.struct2()   # Here you was redefining self.struct1
    

    I changed to:

    self.struct1 = self.struct1()
    self.struct2 = self.struct2()