简体   繁体   中英

Read python dict or yaml and call as python function with arguments and objects

To read the below python dict or its equivalent yaml and generate equivalent python function call

mydict = {'RouteAdd': {'route_config': {'RouteConfig': {'table_name': 'my table', 'app_id': 'my app', 'nexthops': [{'NexthopInfo': {'nexthop_index': 2, 'nexthop_address': {'GatewayAddress': {'ethernet_mac': 'my mac', 'nexthop_ip': 'my ip'}}, 'if_name': 'my interface'}}]}}}}

Its yaml(for readability):

RouteAdd:
  route_config:
    RouteConfig:
      app_id: "my app"
      nexthops:
      - NexthopInfo:
          if_name: "my interface"
          nexthop_address:
            GatewayAddress:
              ethernet_mac: "my mac"
              nexthop_ip: "my ip"
          nexthop_index: 2
      table_name: "my table"

I would like to read the above kind of yaml or python dict and call as below:

RouteAdd(route_config=Routeconfig(app_id="my app",nexthops=[NexthopInfo(if_name="my interface",nexthop_address=GatewayAddress(ethernet_mac="my mac",nexthop_ip="my ip"),nexthop_index=2)],table_name="my table"))

Basically alternate hierarchy is an object. What I have pasted is a small clip. Looking for a recursive function that does this by reading either a yaml or python dict and convert it to above format so that I can call and execute the function. Any help is much appreciated. Thanks

Try this:

def call_dict(d):
    k, v = list(d.items())[0]  # ('RouteAdd', {route_config: ...})
    kwargs = {}
    for k2, v2 in v.items():
        if isinstance(v2, dict):
            kwargs[k2] = call_dict(v2)
        elif isinstance(v2, list):
            kwargs[k2] = [(call_dict(v3) if isinstance(v3, dict) else v3) for v3 in v2]
        else:
            kwargs[k2] = v2
    return globals()[k](**kwargs)

Test:

def test1(t_arg=None, t_arg2=None):
    return t_arg + sum(t_arg2)

def test2(t_arg=None):
    return t_arg


res = test1(t_arg=1, t_arg2=[test2(t_arg=2), test2(t_arg=3)])
print(res)  # 6


test_dict = {
    'test1': {
        't_arg': 1,
        't_arg2': [
            {'test2': {'t_arg': 2}},
            {'test2': {'t_arg': 3}},
        ]
    }
}

res = call_dict(test_dict)
print(res)  # 6

Upd:

As string of code:

def str_of_code(d):
    k, v = list(d.items())[0]
    kwargs = {}
    for k2, v2 in v.items():
        if isinstance(v2, dict):
            kwargs[k2] = str_of_code(v2)
        elif isinstance(v2, list):
            kwargs[k2] = '[{}]'.format(', '.join(
                (str_of_code(v3) if isinstance(v3, dict) else repr(v3)) for v3 in v2)
            )
        else:
            kwargs[k2] = repr(v2)
    return '{}({})'.format(k, ', '.join('{}={}'.format(*i) for i in kwargs.items()))


test_dict = {
    'test1': {
        't_arg': 1,
        't_arg2': [
            {'test2': {'t_arg': 2}},
            {'test2': {'t_arg': 3}},
        ]
    }
}

res = str_of_code(test_dict)
print(res)  # test1(t_arg=1, t_arg2=[test2(t_arg=2), test2(t_arg=3)])

Tried all the methods available suggested in the forum, but somehow none was working out for the solution that I was looking for. Hence, being a beginner, solved it by the below unorthodox way of finding and replacing. If someone have a better solution, please post it and I would like to use it.

api_map_complete = {api: {'config': {'AddressConfig': {'unit': 0, 'port_name': "my_name", 'address': "my address", 'family': 2}}}} 

def dict_to_obj(mystr,flag):
    global api_string
    if re.search(':\(',mystr):    
        if flag % 2 == 0:    
            api_string=mystr.replace(":(","(",1)
            flag=flag+1
        else:
            api_string=mystr.replace(":("," = (",1)
            flag=flag+1
        dict_to_obj(api_string,flag)
    else:    
        mystr=mystr.replace(":"," = ")
        mystr=mystr.replace(",",", ")
        api_string=mystr    

for combo in api_map_complete:    

    api_name=combo.keys()[0]
    for k,v in combo.iteritems():
        api_string=str(v)
        api_string=api_string.replace("{","(")
        api_string=api_string.replace("}",")")
        api_string=api_string.replace(" ","")
        api_string=api_string.replace(":'",":\"")
        api_string=api_string.replace("',","\",")
        api_string=api_string.replace("')","\")")
        api_string=api_string.replace("'","")
        dict_to_obj(api_string,1)
    #print api_string
    api_obj=api_name+api_string
    print api_obj

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM