未解之谜


1

{1, 2}
{1: 2}
{1, [2]}  # typeerror


TypeError: unhashable type: 'list'



2

总结:

tomlkit.items.Array 不能str 可以repr


双层dict

以下内容 jupyter 运行没问题 cyc报错

原因 list没有转为str

import tomlkit

def convert_dict_to_str(input_dict):
    if isinstance(input_dict, dict):
        return {str(k): convert_dict_to_str(v) for k, v in input_dict.items()}
    else:
        return str(input_dict)

with open(path_config, "r") as f:
    doc_config = tomlkit.parse(f.read())

dic_config = convert_dict_to_str(doc_config)

报错 AttributeError: 'str' object has no attribute 'value'


import tomlkit

def convert_dict_to_str(input_dict):
    if isinstance(input_dict, dict):
        try:
            return {str(k): convert_dict_to_str(v) for k, v in input_dict.items()}
        except:
            return str(input_dict)
    else:
        return str(input_dict)

with open(path_config, "r") as f:
    doc_config = tomlkit.parse(f.read())

dic_config = convert_dict_to_str(doc_config)
print(dic_config["table_column"]["column_5"])

TypeError: string indices must be integers

# dic_config["table_column"]对应的键值已经是字符串了





def convert_dict_to_str(input_dict):
    if isinstance(input_dict, dict):
        try:
            return {str(k): convert_dict_to_str(v) for k, v in input_dict.items()}
        except:
            return {str(k): str(v) for k, v in input_dict.items()}
    else:
        return str(input_dict)

with open(path_config, "r") as f:
    doc_config = tomlkit.parse(f.read())

dic_config = convert_dict_to_str(doc_config)
# print(dic_config["table_column"]["column_5"])
# type: str
# TypeError: string indices must be integers


# dic_config["table_column"]对应的键值已经是字符串了

看最下面!!!!


import tomlkit

def convert_dict_to_str(input_dict):
    if isinstance(input_dict, dict):
        try:
            return {str(k): convert_dict_to_str(v) for k, v in input_dict.items()}
        except:
            print(input_dict)
    else:
        return str(input_dict)

with open(path_config, "r") as f:
    doc_config = tomlkit.parse(f.read())

dic_config = convert_dict_to_str(doc_config)
print(dic_config["table_column"])  # None

# jupyter没有这个问题


改写效果一致

以下内容 jupyter 运行没问题 cyc报错

import tomlkit

def convert_dict_to_str(input_dict):
    dic_parent = {}
    for i, j in input_dict.items():
        dic_child = {}
        for m, n in j.items():
            dic_child[str(m)] = str(n)
        dic_parent[str(i)] = dic_child
    return dic_parent

with open(path_config, "r") as f:
    doc_config = tomlkit.parse(f.read())

dic_config = convert_dict_to_str(doc_config)


再改写

import tomlkit

def convert_dict_to_str(input_dict):
    dic_parent = {}
    for i, j in input_dict.items():
        dic_child = {}
        for m, n in j.items():
            try:
                dic_child[str(m)] = str(n)
            except:
                print(m, type(m))
                print(type(n))
                # 无法print(n)
                # <class 'tomlkit.items.Array'>
        dic_parent[str(i)] = dic_child
    return dic_parent

with open(path_config, "r") as f:
    doc_config = tomlkit.parse(f.read())

dic_config = convert_dict_to_str(doc_config)


找到问题了!

cyc的版本里

tomlkit.items.Array 无法使用函数 print str 

list tuple 貌似可以 但有一次不行

可以使用函数 type repr


0

下次遇到这种问题debug方法是 遍历 检查类型


1

且repr(字符串形式的列表) 与 repr(列表形式的列表) 不一样 前者会将双引号也格式化

即不要

def convert_dict_to_str(input_dict):
    dic_parent = {}
    for i, j in input_dict.items():
        dic_child = {}
        for m, n in j.items():
            dic_child[str(m)] = repr(n)
        dic_parent[str(i)] = dic_child
    return dic_parent

2

而是

def convert_dict_to_str(input_dict):
    dic_parent = {}
    for i, j in input_dict.items():
        dic_child = {}
        for m, n in j.items():
            try:
                dic_child[str(m)] = str(n)
            except:
                dic_child[str(m)] = repr(n)
        dic_parent[str(i)] = dic_child
    return dic_parent


3

再改回递归的方法 限 识别 tomlkit.items.Array

import tomlkit

def convert_dict_to_str(input_dict):
    if isinstance(input_dict, tomlkit.items.Array):
        return repr(input_dict)
    elif isinstance(input_dict, dict):
        return {str(k): convert_dict_to_str(v) for k, v in input_dict.items()}
    else:
        return str(input_dict)
        
with open(path_config, "r") as f:
    doc_config = tomlkit.parse(f.read())

dic_config = convert_dict_to_str(doc_config)
print(dic_config["table_column"]["column_5"])


4

或者 只要类似的情况 不限 tomlkit.items.Array

这样不行哦

def convert_dict_to_str(input_dict):
    if isinstance(input_dict, dict):
        try:
            return {str(k): convert_dict_to_str(v) for k, v in input_dict.items()}
        except:
            return repr(input_dict)
    else:
        return str(input_dict)

这样会将dic_config["table_column"]对应的键值都变成字符串

跟下面一样

def convert_dict_to_str(input_dict):
    if isinstance(input_dict, dict):
        try:
            return {str(k): convert_dict_to_str(v) for k, v in input_dict.items()}
        except:
            return {str(k): str(v) for k, v in input_dict.items()}
    else:
        return str(input_dict)

改成下面这样 就可以了!

import tomlkit

def convert_dict_to_str(input_dict):
    if isinstance(input_dict, dict):
        try:
            return {str(k): convert_dict_to_str(v) for k, v in input_dict.items()}
        except:
            return {str(k): repr(v) for k, v in input_dict.items()}
    else:
        return str(input_dict)

with open(path_config, "r") as f:
    doc_config = tomlkit.parse(f.read())

dic_config = convert_dict_to_str(doc_config)
print(dic_config["table_column"]["column_5"])

还可以改成这样

允许 tomlkit.items.Array 转list 但有一次不知道为啥不行

import tomlkit

with open(path_config, "r") as f:
    doc_config = tomlkit.parse(f.read())

type(doc_config["table_column"]["column_5"])
# tomlkit.items.Array

list(doc_config["table_column"]["column_5"])
tuple(doc_config["table_column"]["column_5"])
# can run on both jupyter and cyc
# str(doc_config["table_column"]["column_5"])
# can run on jupyter but not on cyc

def convert_dict_to_str(input_dict):
    if isinstance(input_dict, dict):
        try:
            return {str(k): convert_dict_to_str(v) for k, v in input_dict.items()}
        except:
            return {str(k): str(list(v)) for k, v in input_dict.items()}
    else:
        return str(input_dict)

dic_config = convert_dict_to_str(doc_config)
print(dic_config["table_column"]["column_5"])

效果一致

import tomlkit

with open(path_config, "r") as f:
    doc_config = tomlkit.parse(f.read())

type(doc_config["table_column"]["column_5"])
# tomlkit.items.Array

list(doc_config["table_column"]["column_5"])
tuple(doc_config["table_column"]["column_5"])
# can run on both jupyter and cyc
# str(doc_config["table_column"]["column_5"])
# can run on jupyter but not on cyc

def convert_dict_to_str(input_dict):
    if isinstance(input_dict, dict):
        try:
            return {str(k): convert_dict_to_str(v) for k, v in input_dict.items()}
        except:
            return {str(k): str(list(v)) for k, v in input_dict.items()}
    else:
        return str(input_dict)

dic_config = convert_dict_to_str(doc_config)
res_1 = dic_config["table_column"]["column_5"]


def convert_dict_to_str(input_dict):
    if isinstance(input_dict, dict):
        try:
            return {str(k): convert_dict_to_str(v) for k, v in input_dict.items()}
        except:
            return {str(k): repr(v) for k, v in input_dict.items()}
    else:
        return str(input_dict)

dic_config = convert_dict_to_str(doc_config)
res_2 = dic_config["table_column"]["column_5"]

print(res_1==res_2, type(res_1), type(res_2))


这个对象在cyc 有value属性 但 没有办法打印 和格式化为字符串

toml_arr = doc_config["table_column"]["column_5"]
type(toml_arr)
# tomlkit.items.Array

# print(str(toml_arr))
# print(f"{toml_arr}")
# print("{}".format(toml_arr))
# can run on jupyter but not on cyc
# return str([v.value.value for v in self._iter_items() if v.value is not None])
# AttributeError: 'str' object has no attribute 'value'

# 查看属性
"value" in dir(toml_arr)
toml_arr.value
# print(toml_arr.value)
# attribute value exists in both jupyter and cyc
# but cyc cannot print it

hasattr(toml_arr, "value")
# both true and both can print

getattr(toml_arr, "value")
# both tur but cannot print on cyc

6 又出现了问题

list_column = eval(dic_config["table_column"]["column_2"])
print(type(list_column))
# jupyter list but cyc str

7 解决

import tomlkit
path_config = r"\\172.18.6.33\hflvfile\机器人项目\华峰铝业RPA\文件\配置表\生产月结\包装_migo退库\config.toml"

with open(path_config, "r") as f:
    doc_config = tomlkit.parse(f.read())


# both list
# ok
def convert_dict_to_str(input_dict):
    if isinstance(input_dict, tomlkit.items.Array):
        return repr(input_dict)
    elif isinstance(input_dict, dict):
        return {str(k): convert_dict_to_str(v) for k, v in input_dict.items()}
    else:
        return str(input_dict)

# both list
# but on cyc it splited to single character
# cyc eval(str(list(tomlkit.items.Array)))
def convert_dict_to_str(input_dict):
    if isinstance(input_dict, dict):
        try:
            return {str(k): convert_dict_to_str(v) for k, v in input_dict.items()}
        except:
            return {str(k): str(list(v)) for k, v in input_dict.items()}
    else:
        return str(input_dict)

# jupyter list but cyc str
def convert_dict_to_str(input_dict):
    if isinstance(input_dict, dict):
        try:
            return {str(k): convert_dict_to_str(v) for k, v in input_dict.items()}
        except:
            return {str(k): repr(v) for k, v in input_dict.items()}
    else:
        return str(input_dict)
    
dic_config = convert_dict_to_str(doc_config)

list_column = eval(dic_config["table_column"]["column_2"])
print(type(list_column))
print(list_column)