2017-05-24 26 views
2

私はPyYAMLとして以下のYAML文字列を解釈したい:PyYAMLとネストされたオブジェクト

 - !Table 
     header: 
      - !Column 
      - !Paragraph 
       text: 'header1' 
      - !Column 
      - !Paragraph 
       text: 'header2' 

私はyaml.YAMLObjectクラスから継承されている表と段落のクラスを持っています。しかし、私は!Columnタグについて何をすべきかわからないのですか?このタグは、名前付き配列タグとしてのみ扱う必要があります。

私はyaml.load()関数からオブジェクトを構築したい場合は、私はエラー以下しまっ:

yaml.constructor.ConstructorError: could not determine a constructor 
for the tag '!Column' 
in "<unicode string>", line 19, column 17: 
       - !Column 
       ^
+0

「名前付き配列」とは何ですか?名前付きタプルを意味しますか?そのタグのコンストラクタを追加する必要があり、(段落の)シーケンスを取得します。あなたは名前として何を期待していますか? – Anthon

+0

@Anthon私が追加したのは、読みやすさを向上させるためだけのファイルのcolumnタグです。名前付き配列が間違っています。つまり、列は、読みやすさを高め、条約に着目するための名前です。 – memlucky

+0

第2段落の前に '!'がありませんでした。 – Anthon

答えて

0

yaml.YAMLObjectを使用して2つの問題があります。

  • はデフォルト以外のものを使用する透過的ではありませんyaml.Loaderあなたが入力を完全に制御できない限り、あなたが行うべきでない不安全なyaml.load()をあなたに強制することができます。
  • スカラーまたはシーケンスで構成されるノードであるオブジェクトには使用できません。マッピングのみが使用できます。

!Table!Paragraphはマッピングノードです。しかし、あなたの!Columnがシーケンスで、あなたが明示的にそのためのコンストラクタを作成する必要があります。

import sys 
from ruamel import yaml 

yaml_str = """\ 
- !Table 
    header: 
    - !Column 
     - !Paragraph 
     text: 'header1' 
    - !Column 
     - !Paragraph 
     text: 'header2' 

""" 

class Table(yaml.YAMLObject): 
    yaml_tag = u'!Table' 
    pass 


class Paragraph(yaml.YAMLObject): 
    yaml_tag = u'!Paragraph' 
    pass 

def column_constructor(loader, node): 
    return loader.construct_sequence(node) 

yaml.add_constructor('!Column', column_constructor) 


data = yaml.load(yaml_str) 
yaml.dump(data, sys.stdout, default_flow_style=False) 

この版画:

- !Table 
    header: 
    - - !Paragraph 
     text: header1 
    - - !Paragraph 
     text: header2 

とを(私はruamel.yamlを使用しているため、またUnsafeLoaderWarning)。

あなたは出力が!Columnを含める場合、あなたはPythonのクラス​​をしなければならないとcolumn_constructorがそのタイプをお返しし、さらにColumnためrepresenterを書いて、ローダにそれを追加しています。

+0

非常に便利です。ありがとう – memlucky

関連する問題