私はこれを持っています:
user_dir: /home/user
user_pics: /home/user/pics
user_dir
for user_pics?このような他のプロパティを指定する必要がある場合、あまり乾燥していません。
次のように、繰り返しノードを使用できます。
user_dir: &user_home /home/user
user_pics: *user_home
しかし、連結できるとは思わないので、これはないでしょう動作します:
user_dir: &user_home /home/user
user_pics: *user_home/pics
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'}
文字列を区切る必要がある場合は、" "
や"-"
などのアイテムを配列に追加できます。
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], /]
配列を使用してから、現在のOS区切り記号と文字列を結合します
このような:
default: &default_path "you should not use paths in config"
pictures:
- *default_path
- pics
YAML自体 これを行う方法を定義しない のように思えます。
良いニュースは、YAMLコンシューマーが変数を理解できる可能性があることです。
YAMLは何を使用しますか?
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)
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)
_
詳細については、 このGitHubの問題 を参照してください。