mCs
mCs

Reputation: 2911

How to search if object (or its subobjects) contain a field of given name and verify its value

I am after python3 here as my app is using only python3.

Let's say we have:

class A:
   def __init__(self):
     self.Ap1 = 'Ap1val'
     self.Ap2 = 'Ap2val'
     self.Ap3 = 'Ap3val'

class B:
   def __init__(self):
     self.Bp1 = 'Bp1val'
     self.Bp2 = 'Bp2val'
     self.Bp3 = A()

class C:
   def __init__(self):
     self.Cp1 = 'Cp1val'
     self.Cp2 = 'Cp2val'
     self.Cp3 = B()

I want to get a dictionary of field_name:field_value while in case of sub-objects a new dictionary would start with the same pattern. So that I could search it for the given field name value.

So in this case for C object it would be like:

{ 'C' : { 
         'Cp1' = 'Cp1val',
         'Cp2' = 'Cp2val',
         'Cp3' = { 
                  'B': {
                           'Bp1' : 'Bp1val'
                           'Bp2' : 'Bp2val'
                           'Bp3' : {
                                     'A': {
                                             'Ap1' : 'Ap1val'
                                             'Ap2' : 'Ap2val'
                                             'Ap3' : 'Ap3val'
                                          }
                                   }
                       }
                 }
        }
}

I have found the dir() function, but it only works for the top object, not getting deeper. So the dir(c) is not enough as I need to get to the subobject too. A recursion will apply here well I gues.

EDIT When I try to find value for key in object like this:

def gp(class_inst, key):
    properties = [prop for prop in dir(class_inst) if not prop.startswith('__')]

    for prop in properties:
        value = class_inst.__getattribute__(prop)
        if isinstance(value, str):
            print('{}:{} {} {}'.format(prop, value, prop == key, key))
            if prop == key:
                print(value)
                return value
        else:
            gp(value, key)

    return None

print('Bp2' == 'Bp2')
print(gp(C(), 'Bp2'))

I keep getting None even after the return statement even though it is entering the return block. WHY?

Upvotes: 0

Views: 332

Answers (1)

marcos
marcos

Reputation: 4510

It's very simple just use a recursive function to look for nested properties that are not strings, for example:

class A:
   def __init__(self):
     self.Ap1 = 'Ap1val'
     self.Ap2 = 'Ap2val'
     self.Ap3 = 'Ap3val'

class B:
   def __init__(self):
     self.Bp1 = 'Bp1val'
     self.Bp2 = 'Bp2val'
     self.Bp3 = A()

class C:
   def __init__(self):
     self.Cp1 = 'Cp1val'
     self.Cp2 = 'Cp2val'
     self.Cp3 = B()


def get_properties(class_inst):
    properties = [prop for prop in dir(class_inst) if not prop.startswith('__')]

    output = {}
    for prop in properties:
        value = class_inst.__getattribute__(prop)
        if isinstance(value, str):
            output[prop] = value
        else:
            output[prop] = get_properties(value)

    return {type(class_inst).__name__: output}


print(get_properties(C()))

>>> {'C': {'Cp1': 'Cp1val', 'Cp2': 'Cp2val', 'Cp3': {'B': {'Bp1': 'Bp1val', 'Bp2': 'Bp2val', 'Bp3': {'A': {'Ap1': 'Ap1val', 'Ap2': 'Ap2val', 'Ap3': 'Ap3val'}}}}}}

Upvotes: 1

Related Questions