我有一个YAML文件描述我的对象和
--- !MyData
name: theName
param: parameter
data_file: \\path\to\my\file.csv
我的代码如下
class Load(Parent):
def __init__(self, name="",
param = param,
useDataFile=False,
data_file = "none",
**kwargs):
super().__init__(name=name,
data_file = data_file)
def load_constructor(loader, node):
values = loader.construct_mapping(node, deep=True)
return Load(**values)
yaml.add_constructor(u'!Load', load_constructor)
在初始时,main使用它来加载数据
with open(self.initFile, 'r', newline='') as ymlfile:
for item in yaml.load_all(ymlfile):
if type(item) is Load:
---- some post init code
一切正常但是因为我的主代码已经知道 data_file 的完整路径,因为它与yaml位于同一目录中, 有没有办法只给出 data_file 的名称而没有完整路径,以便我可以在不编辑yaml配置文件的情况下更改位置?由于 data_file 由通过 yaml.load_all 函数调用的Parent类加载,我不知道如何给出一个告诉路径值的参数。
答案 0 :(得分:0)
有许多不同的解决方案可以在Load实例中动态获取变量path
,包括:
path
工厂设置load_constructor
直接调用工厂而不是Load
。path
并使其__call__
方法执行构造后者可以用:
import ruamel.yaml as yaml
yaml_str = """\
--- !MyData
name: theName
param: parameter
data_file: file.csv
"""
class Parent:
def __init__(self, name, data_file, path=None):
self._name = name
self._data_file = (path + data_file) if path is not None else data_file
class Load(Parent):
def __init__(self, name="",
param = "param",
useDataFile=False,
data_file = "none",
path=None,
**kwargs):
super().__init__(name=name,
data_file = data_file, path=path)
class LoadConstructor:
def __init__(self, path=None):
self._path = None
def set_path(self, path):
self._path = path
def __call__(self, loader, node):
values = loader.construct_mapping(node, deep=True)
values['path'] = self._path
return Load(**values)
load_constructor = LoadConstructor()
yaml.add_constructor(u'!MyData', load_constructor)
# using the above:
# set the default path
load_constructor.set_path('/my/path/to/csv/')
# parse YAML documents
for item in yaml.load_all(yaml_str):
if type(item) is Load:
print('data file:', item._data_file)
请注意,我必须更改构造函数的第一个参数,否则无法构造类型为MyData
的YAML对象。如果您将param
用作Load.__init__()
的值(因为关键当然没问题),也需要定义data file: /my/path/to/csv/file.csv
,所以我引用了它。
运行上面的内容(在Python3下)将为您提供:
config.xml