我有这个:
user_dir: /home/user
user_pics: /home/user/pics
我怎样才能将user_dir
用于user_pics?如果我必须指定这样的其他属性,它将不会非常干。
答案 0 :(得分:38)
您可以使用重复的节点,如下所示:
user_dir: &user_home /home/user
user_pics: *user_home
我认为你不能连接,所以不会工作:
user_dir: &user_home /home/user
user_pics: *user_home/pics
答案 1 :(得分:27)
令人惊讶的是,因为YAML的目的是锚定&引用是因为YAML数据文件中的重复因素,没有内置的方法来使用引用连接字符串。从部件构建路径名的用例就是一个很好的例子 - 必须有很多这样的用途。
幸运的是,有一种简单的方法可以通过Python中的自定义标记向YAML添加字符串连接。
import yaml
## define custom tag handler
def join(loader, node):
seq = loader.construct_sequence(node)
return ''.join([str(i) for i in seq])
## register the tag handler
yaml.add_constructor('!join', join)
## using your sample data
yaml.load("""
user_dir: &DIR /home/user
user_pics: !join [*DIR, /pics]
""")
结果是:
{'user_dir': '/home/user', 'user_pics': '/home/user/pics'}
如果字符串应该分隔,您可以向数组中添加更多项目,例如" "
或"-"
。
答案 2 :(得分:10)
如果您在PyYaml中使用python,则可以在YAML文件中加入字符串。不幸的是,这只是一个python解决方案,而不是一个普遍的解决方案:
os.path.join
:
user_dir: &home /home/user
user_pics: !!python/object/apply:os.path.join [*home, pics]
string.join
(为了完整起见 - 此方法可以灵活地用于多种形式的字符串连接:
user_dir: &home /home/user
user_pics: !!python/object/apply:string.join [[*home, pics], /]
答案 3 :(得分:6)
我会使用数组,然后将字符串与当前的OS分隔符符号
连接在一起 像这样:default: &default_path "you should not use paths in config"
pictures:
- *default_path
- pics
答案 4 :(得分:3)
我觉得YAML本身does not define way to do this。
好消息是YAML消费者可能能够理解变量 什么会使用你的YAML?
答案 5 :(得分:0)
string.join()
在Python3中不起作用,但是您可以这样定义!join
:
import functools
import yaml
class StringConcatinator(yaml.YAMLObject):
yaml_loader = yaml.SafeLoader
yaml_tag = '!join'
@classmethod
def from_yaml(cls, loader, node):
return functools.reduce(lambda a, b: a.value + b.value, node.value)
c=yaml.safe_load('''
user_dir: &user_dir /home/user
user_pics: !join [*user_dir, /pics]''')
print(c)
答案 6 :(得分:0)
截至2019年8月:
要使Chris'解决方案有效,您实际上需要向Loader=yaml.Loader
添加yaml.load()
。最终,代码将如下所示:
import yaml
## define custom tag handler
def join(loader, node):
seq = loader.construct_sequence(node)
return ''.join([str(i) for i in seq])
## register the tag handler
yaml.add_constructor('!join', join)
## using your sample data
yaml.load("""
user_dir: &DIR /home/user
user_pics: !join [*DIR, /pics]
""", Loader=yaml.Loader)
有关进一步的讨论,请参见this GitHub issue。