CommentedMap.update() 不保留评论
CommentedMap.update() not preserving comments
我不确定我是否从正确的角度解决了这个问题,如果您有其他看法,请告诉我。
使用 ruamel.yaml 模块,我想在将它们转储并保留其注释之前获得一些配置文件的表示。
为此我基本上有:
#!/usr/bin/env python3.5
from ruamel.yaml import YAML
class MyYaml():
def __init__(self, cm):
self.yaml = YAML()
self.yaml.default_flow_style = False
self.cm = cm
def load_main_config_file(self, path):
if isinstance(path, str):
with open(path, 'r') as config_file:
self.cm.update(self.yaml.load(config_file))
# cannot be self.cm = self.yaml.load(config_file)
# because it would change the id of self.cm
# the dict would not be accessible from outside anymore
def load_config_file(self, path_key_list, target_dict = None):
for file_path,key_list in path_key_list:
with open(file_path, 'r') as config_file:
self.update_dict((target_dict if target_dict is not None else self.cm), key_list, self.yaml.load(config_file))
def update_dict(self, my_dict, key_list, value):
"""
Works fine to preserve comments but cannot be used for the main config file as the dict is empty
"""
for k in key_list[:-1]:
my_dict = my_dict.setdefault(k, {})
my_dict[key_list[-1]] = value
from ruamel.yaml.comments import CommentedMap
from copy import deepcopy
class Parent():
def __init__(self):
self.__cm = CommentedMap() # private so users cannot modify
self.Yaml = MyYaml(self.__cm)
@property
def cm(self):
return deepcopy(self.__cm)
from ruamel.yaml import YAML
import sys
class Child(Parent):
def __init__(self):
super().__init__()
yaml = YAML()
self.Yaml.load_main_config_file("path_to_file")
print("\n\n############################")
print("Main load : ")
print("############################")
yaml.dump(self.cm, sys.stdout)
print("\n\n############################")
print("Other load :")
print("############################")
self.Yaml.load_config_file([("path_to_file",["other_file"])])
yaml.dump(self.cm, sys.stdout)
if __name__ == "__main__":
ch = Child()
我得到了这个输出:
############################
Main load :
############################
key1: val1
key2: val2
key3:
key31: val31
key32: val32
key4:
key41: val41
############################
Other load :
############################
key1: val1
key2: val2
key3:
key31: val31
key32: val32
key4:
key41: val41
other_file:
############
# ! TEST ! #
############
key1: val1
# Comment 1
key2: val2
#this is a comment
key3:
key31: val31
key32: val32
key4:
key41: val41
有什么建议可以让第一个配置文件保留注释吗?
PS :这是我第一次 post 在这里,我希望它足够清楚。感谢您的宝贵时间!
在线:
self.cm.update(self.yaml.load(config_file))
load()
returns一个CommentedMap()
,从中更新只使用key
值对。如果你想复制评论:
tmp_cm = self.yaml.load(config_file)
self.cm.update(tmp_cm)
tmp_cm.copy_attributes(self.cm)
如果您想保留 self.cm 上任何已经存在的评论,对于键
不会更新的,您应该检查 .ca
属性并执行
更新相关项目,而不是完全覆盖评论。
请注意,此“内部数据”不保证保持稳定,
所以固定你的 ruamel.yaml 版本,并在更改该版本之前进行测试。
您还应该考虑更新 Python 版本,因为 3.5 已停产
ruamel.yaml 中的支持将随着下一次次要版本升级而下降。
完整节目:
import sys
from ruamel.yaml import YAML
class MyYaml():
def __init__(self, cm):
self.yaml = YAML()
self.yaml.default_flow_style = False
self.cm = cm
def load_main_config_file(self, path):
if isinstance(path, str):
with open(path, 'r') as config_file:
tmp_cm = self.yaml.load(config_file)
self.cm.update(tmp_cm)
tmp_cm.copy_attributes(self.cm)
# cannot be self.cm = self.yaml.load(config_file)
# because it would change the id of self.cm
# the dict would not be accessible from outside anymore
def load_config_file(self, path_key_list, target_dict = None):
for file_path,key_list in path_key_list:
with open(file_path, 'r') as config_file:
self.update_dict((target_dict if target_dict is not None else self.cm), key_list, self.yaml.load(config_file))
def update_dict(self, my_dict, key_list, value):
"""
Works fine to preserve comments but cannot be used for the main config file as the dict is empty
"""
for k in key_list[:-1]:
my_dict = my_dict.setdefault(k, {})
my_dict[key_list[-1]] = value
from ruamel.yaml.comments import CommentedMap
from copy import deepcopy
class Parent():
def __init__(self):
self.__cm = CommentedMap() # private so users cannot modify
self.Yaml = MyYaml(self.__cm)
@property
def cm(self):
return deepcopy(self.__cm)
from ruamel.yaml import YAML
import sys
class Child(Parent):
def __init__(self):
super().__init__()
yaml = YAML()
self.Yaml.load_main_config_file("path_to_file")
print("\n\n############################")
print("Main load : ")
print("############################")
yaml.dump(self.cm, sys.stdout)
print("\n\n############################")
print("Other load :")
print("############################")
self.Yaml.load_config_file([("path_to_file",["other_file"])])
yaml.dump(self.cm, sys.stdout)
if __name__ == "__main__":
ch = Child()
给出:
############################
Main load :
############################
key1: val1
# Comment 1
key2: val2
#this is a comment
key3:
key31: val31
key32: val32
key4:
key41: val41
############################
Other load :
############################
key1: val1
# Comment 1
key2: val2
#this is a comment
key3:
key31: val31
key32: val32
key4:
key41: val41
other_file:
key1: val1
# Comment 1
key2: val2
#this is a comment
key3:
key31: val31
key32: val32
key4:
key41: val41
请注意,“嵌套”文件中的注释不会缩进,您
将不得不遍历各个评论并更改他们的开始列来实现这一点。
我不确定我是否从正确的角度解决了这个问题,如果您有其他看法,请告诉我。
使用 ruamel.yaml 模块,我想在将它们转储并保留其注释之前获得一些配置文件的表示。
为此我基本上有:
#!/usr/bin/env python3.5
from ruamel.yaml import YAML
class MyYaml():
def __init__(self, cm):
self.yaml = YAML()
self.yaml.default_flow_style = False
self.cm = cm
def load_main_config_file(self, path):
if isinstance(path, str):
with open(path, 'r') as config_file:
self.cm.update(self.yaml.load(config_file))
# cannot be self.cm = self.yaml.load(config_file)
# because it would change the id of self.cm
# the dict would not be accessible from outside anymore
def load_config_file(self, path_key_list, target_dict = None):
for file_path,key_list in path_key_list:
with open(file_path, 'r') as config_file:
self.update_dict((target_dict if target_dict is not None else self.cm), key_list, self.yaml.load(config_file))
def update_dict(self, my_dict, key_list, value):
"""
Works fine to preserve comments but cannot be used for the main config file as the dict is empty
"""
for k in key_list[:-1]:
my_dict = my_dict.setdefault(k, {})
my_dict[key_list[-1]] = value
from ruamel.yaml.comments import CommentedMap
from copy import deepcopy
class Parent():
def __init__(self):
self.__cm = CommentedMap() # private so users cannot modify
self.Yaml = MyYaml(self.__cm)
@property
def cm(self):
return deepcopy(self.__cm)
from ruamel.yaml import YAML
import sys
class Child(Parent):
def __init__(self):
super().__init__()
yaml = YAML()
self.Yaml.load_main_config_file("path_to_file")
print("\n\n############################")
print("Main load : ")
print("############################")
yaml.dump(self.cm, sys.stdout)
print("\n\n############################")
print("Other load :")
print("############################")
self.Yaml.load_config_file([("path_to_file",["other_file"])])
yaml.dump(self.cm, sys.stdout)
if __name__ == "__main__":
ch = Child()
我得到了这个输出:
############################
Main load :
############################
key1: val1
key2: val2
key3:
key31: val31
key32: val32
key4:
key41: val41
############################
Other load :
############################
key1: val1
key2: val2
key3:
key31: val31
key32: val32
key4:
key41: val41
other_file:
############
# ! TEST ! #
############
key1: val1
# Comment 1
key2: val2
#this is a comment
key3:
key31: val31
key32: val32
key4:
key41: val41
有什么建议可以让第一个配置文件保留注释吗?
PS :这是我第一次 post 在这里,我希望它足够清楚。感谢您的宝贵时间!
在线:
self.cm.update(self.yaml.load(config_file))
load()
returns一个CommentedMap()
,从中更新只使用key
值对。如果你想复制评论:
tmp_cm = self.yaml.load(config_file)
self.cm.update(tmp_cm)
tmp_cm.copy_attributes(self.cm)
如果您想保留 self.cm 上任何已经存在的评论,对于键
不会更新的,您应该检查 .ca
属性并执行
更新相关项目,而不是完全覆盖评论。
请注意,此“内部数据”不保证保持稳定, 所以固定你的 ruamel.yaml 版本,并在更改该版本之前进行测试。 您还应该考虑更新 Python 版本,因为 3.5 已停产 ruamel.yaml 中的支持将随着下一次次要版本升级而下降。
完整节目:
import sys
from ruamel.yaml import YAML
class MyYaml():
def __init__(self, cm):
self.yaml = YAML()
self.yaml.default_flow_style = False
self.cm = cm
def load_main_config_file(self, path):
if isinstance(path, str):
with open(path, 'r') as config_file:
tmp_cm = self.yaml.load(config_file)
self.cm.update(tmp_cm)
tmp_cm.copy_attributes(self.cm)
# cannot be self.cm = self.yaml.load(config_file)
# because it would change the id of self.cm
# the dict would not be accessible from outside anymore
def load_config_file(self, path_key_list, target_dict = None):
for file_path,key_list in path_key_list:
with open(file_path, 'r') as config_file:
self.update_dict((target_dict if target_dict is not None else self.cm), key_list, self.yaml.load(config_file))
def update_dict(self, my_dict, key_list, value):
"""
Works fine to preserve comments but cannot be used for the main config file as the dict is empty
"""
for k in key_list[:-1]:
my_dict = my_dict.setdefault(k, {})
my_dict[key_list[-1]] = value
from ruamel.yaml.comments import CommentedMap
from copy import deepcopy
class Parent():
def __init__(self):
self.__cm = CommentedMap() # private so users cannot modify
self.Yaml = MyYaml(self.__cm)
@property
def cm(self):
return deepcopy(self.__cm)
from ruamel.yaml import YAML
import sys
class Child(Parent):
def __init__(self):
super().__init__()
yaml = YAML()
self.Yaml.load_main_config_file("path_to_file")
print("\n\n############################")
print("Main load : ")
print("############################")
yaml.dump(self.cm, sys.stdout)
print("\n\n############################")
print("Other load :")
print("############################")
self.Yaml.load_config_file([("path_to_file",["other_file"])])
yaml.dump(self.cm, sys.stdout)
if __name__ == "__main__":
ch = Child()
给出:
############################
Main load :
############################
key1: val1
# Comment 1
key2: val2
#this is a comment
key3:
key31: val31
key32: val32
key4:
key41: val41
############################
Other load :
############################
key1: val1
# Comment 1
key2: val2
#this is a comment
key3:
key31: val31
key32: val32
key4:
key41: val41
other_file:
key1: val1
# Comment 1
key2: val2
#this is a comment
key3:
key31: val31
key32: val32
key4:
key41: val41
请注意,“嵌套”文件中的注释不会缩进,您 将不得不遍历各个评论并更改他们的开始列来实现这一点。