【问题标题】:Read python dict or yaml and call as python function with arguments and objects读取 python dict 或 yaml 并作为带有参数和对象的 python 函数调用
【发布时间】:2016-03-28 19:53:46
【问题描述】:

读取下面的python dict或其等效的yaml并生成等效的python函数调用

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'}}]}}}}

它的 yaml(为了便于阅读):

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"

我想阅读上述的 yaml 或 python dict 并调用如下:

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"))

基本上交替的层次结构是一个对象。我粘贴的是一个小剪辑。寻找一个递归函数,通过读取 yaml 或 python dict 并将其转换为上述格式,以便我可以调用和执行该函数。任何帮助深表感谢。谢谢

【问题讨论】:

    标签: python object dictionary yaml


    【解决方案1】:

    试试这个:

    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)
    

    测试:

    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
    

    更新:

    作为代码串:

    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)])
    

    【讨论】:

    • @germn 感谢您的调查。这很好用,但我想将输出提取为字符串,以将其集成到我的其他工作部分。那么是否可以提取字符串中的调用格式:“test1(t_arg=1, t_arg2=[test2(t_arg=2), test2(t_arg=3)])”。再次感谢。
    • @germn ,它打破了 test_dict = {'test1':{'t_arg':1, 't_arg2':{'t_arg3':[{'a':1},{'b: 2'}]}}}。你能帮忙吗?
    • @Suren 你对此有什么期望?
    • @germn, If test_dict = {'func_name':{'input': {'AsList': {'a_list': [{'AEntry': {'entry':2, 'exit' :3}}]}}}},预期的输出是 func_name(input = AsList(a_list = [AEntry(entry=2, exit=3)]))
    • @Suren 和 str_of_code 为我工作。 (如果您收到错误,请使用此 dict 写入错误消息和行)但它不适用于 {'some':[{'a':1},{'b:2'}]},因为不清楚 {'a':1} 是否是 some 的参数或函数 a 的一部分有错误参数。
    【解决方案2】:

    尝试了论坛中建议的所有可用方法,但不知何故,没有一种方法适合我正在寻找的解决方案。因此,作为初学者,通过以下非正统的查找和替换方式解决了它。如果有人有更好的解决方案,请发布它,我想使用它。

    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
    

    【讨论】:

    • 这不能处理字典列表
    猜你喜欢
    • 2013-08-10
    • 2018-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-14
    • 2017-09-04
    相关资源
    最近更新 更多