2017-05-24 1 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

두 번째 단락 앞에'!'가 누락되었습니다. – Anthon

답변

0

yaml.YAMLObject를 사용하여 두 가지 문제가 있습니다

  • 는 기본 아무것도하지만를 사용하는 투명하지가 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은 다음 파이썬 클래스 Column(list)하고 유형을 돌려주고 column_constructor 있고, 추가로 Column에 대한 representer를 작성하고 로더에 그것을 추가해야합니다 포함합니다.

+0

매우 유용합니다. 감사 – memlucky