Knowhow/Python, Pytorch

python에서 yaml 다루기, PyYAML vs ruamel.yaml

침닦는수건 2023. 6. 9. 18:44
반응형

python에서 yaml을 쓰거나 읽을 때 일반적으로 PyYAML을 사용한다. 검색하면 제일 먼저 나오고 import도 직관적이어서 애용한다. 그리고 웬만한 경우에는 PyYAML로 다 해결되기 때문에 효과적이기도 하다.

pip install PyYAML
###
import yaml

 

PyYAML을 쓰다가 가끔 오류가 나는 경우가 있는데 바로 yaml 최상단에 버전(+ 주석)이 명시된 경우다. camodocal 같은 과거 c++ 기반 툴들을 쓰다보면 이렇게 저장되는 yaml 파일을 볼 수 있는데 이 파일들은 PyYAML로 못 연다. (버전 1.0 이전 같다.)

 

예를 들어, 다음과 같이 yaml 파일이 바로 contents로 시작하지 않고 버전이 명시돼있거나 주석이나 splitter 같은 표기가 들어가있을 경우, PyYAML load가 동작하지 않는다. 

%YAML:1.0
---

 

그럴 경우! ruamel.yaml을 사용해야 한다. 

pip install ruamel.yaml
###
from ruamel import yaml

ruamel.yaml을 사용할 경우, 위와 같이 초반에 버전 명시나 주석처리를 건너뛰고 contents만 읽을 수 있다. 

 

하나 주의 점은, ruamel.yaml이 버전 명시와 주석이 있을 때 읽을 수 있는 것이지 dump 할 때 버전 명시가 자동으로 되는 것은 아니다. 그래서 dump 시 버전 명시를 해서, 즉, %YAML:1.0 같은 것은 표시해주고 싶다면 file write로 써주어야 한다. 

with open(yaml_path, 'w') as yaml_file:
    yaml_file.write("%YAML:1.0\n")
    yaml_file.write("---\n")

 

Tips

우연히 발견한 것인데, PyYAML과 ruamel.yaml의 contents정리 방식이 다르다. 특히 dictionary in dictionary 형태를 저장하는 모양이 다르다. 가령, { "a" : [0, 1, 2], "b" : { "c" : 3, "d" : 4 } } 와 같이 dictionary in dictionary 구조의 데이터가 있다고 해보자.

 

PyYAML의 경우, 다음과 같이 행을 바꾸어가면서 정리한다.

{
    "a" : 0, 1, 2
    "b" :
    	"c" : 3
        "d" : 4
}

 

ruamel.yaml의 경우, 다음과 같이 같은 행에 전부 정리한다.

{
    "a" : 0, 1, 2
    "b" : { "c" : 3, "d" : 4 }
}

 

따라서 정리되는 모양을 보았을 때, PyYAML로 write하는 것이 시각적으로 더 편한 것 같다. 

 

최종적으로 좀 불편하지만 read는 ruamel.yaml로 write는 PyYAML로 하는 것이 어떨지... 사소하지만 PyYAML만 sort_keys=True or False가 가능하기 때문에 순서 정리까지 할 수 있어 더 좋은 것 같다. 

반응형