YAML 파일을 Python 객체로 구문 분석/읽기하는 방법은 무엇입니까?
YAML 파일을 Python 객체로 구문 분석/읽기하는 방법은 무엇입니까?
예를 들어, 이 YAML은 다음과 같습니다.
Person:
name: XYZ
이 Python 클래스의 대상:
class Person(yaml.YAMLObject):
yaml_tag = 'Person'
def __init__(self, name):
self.name = name
참고로 저는 PyYAML을 사용하고 있습니다.
YAML 파일이 다음과 같은 경우:
# tree format
treeroot:
branch1:
name: Node 1
branch1-1:
name: Node 1-1
branch2:
name: Node 2
branch2-1:
name: Node 2-1
그리고 당신은 설치했습니다.PyYAML
다음과 같이:
pip install PyYAML
Python 코드는 다음과 같습니다.
import yaml
with open('tree.yaml') as f:
# use safe_load instead load
dataMap = yaml.safe_load(f)
변수dataMap
이제 트리 데이터가 포함된 사전이 포함되어 있습니다.인쇄하는 경우dataMap
PrettyPrint를 사용하면 다음과 같은 이점을 얻을 수 있습니다.
{
'treeroot': {
'branch1': {
'branch1-1': {
'name': 'Node 1-1'
},
'name': 'Node 1'
},
'branch2': {
'branch2-1': {
'name': 'Node 2-1'
},
'name': 'Node 2'
}
}
}
이제 Python 프로그램에 데이터를 가져오는 방법을 살펴보았습니다.데이터를 쉽게 저장할 수 있습니다.
with open('newtree.yaml', "w") as f:
yaml.dump(dataMap, f)
사전이 있고 이제 Python 객체로 변환해야 합니다.
class Struct:
def __init__(self, **entries):
self.__dict__.update(entries)
그런 다음 다음을 사용할 수 있습니다.
>>> args = your YAML dictionary
>>> s = Struct(**args)
>>> s
<__main__.Struct instance at 0x01D6A738>
>>> s...
"Python dict to object"를 클릭합니다.
자세한 내용은 pyyaml.org 및 이 페이지를 참조하십시오.
http://pyyaml.org/wiki/PyYAMLDocumentation 에서:
add_path_resolver(tag, path, kind)
경로 기반 암시적 태그 확인기를 추가합니다.경로는 표현 그래프에서 노드에 대한 경로를 형성하는 키 목록입니다.경로 요소는 문자열 값, 정수 또는 없음일 수 있습니다.노드의 종류는 str, list, dict 또는 None입니다.
#!/usr/bin/env python
import yaml
class Person(yaml.YAMLObject):
yaml_tag = '!person'
def __init__(self, name):
self.name = name
yaml.add_path_resolver('!person', ['Person'], dict)
data = yaml.load("""
Person:
name: XYZ
""")
print data
# {'Person': <__main__.Person object at 0x7f2b251ceb10>}
print data['Person'].name
# XYZ
저는 이름이 붙은 튜플을 사용하여 구현체를 작성했는데, 이는 조금 읽기 쉽기 때문에 깔끔하다고 생각합니다.또한 사전이 중첩된 경우도 처리합니다.파서 코드는 다음과 같습니다.
from collections import namedtuple
class Dict2ObjParser:
def __init__(self, nested_dict):
self.nested_dict = nested_dict
def parse(self):
nested_dict = self.nested_dict
if (obj_type := type(nested_dict)) is not dict:
raise TypeError(f"Expected 'dict' but found '{obj_type}'")
return self._transform_to_named_tuples("root", nested_dict)
def _transform_to_named_tuples(self, tuple_name, possibly_nested_obj):
if type(possibly_nested_obj) is dict:
named_tuple_def = namedtuple(tuple_name, possibly_nested_obj.keys())
transformed_value = named_tuple_def(
*[
self._transform_to_named_tuples(key, value)
for key, value in possibly_nested_obj.items()
]
)
elif type(possibly_nested_obj) is list:
transformed_value = [
self._transform_to_named_tuples(f"{tuple_name}_{i}", possibly_nested_obj[i])
for i in range(len(possibly_nested_obj))
]
else:
transformed_value = possibly_nested_obj
return transformed_value
다음 코드를 사용하여 기본 사례를 테스트했습니다.
x = Dict2ObjParser({
"a": {
"b": 123,
"c": "Hello, World!"
},
"d": [
1,
2,
3
],
"e": [
{
"f": "",
"g": None
},
{
"f": "Foo",
"g": "Bar"
},
{
"h": "Hi!",
"i": None
}
],
"j": 456,
"k": None
}).parse()
print(x)
다음과 같은 출력을 제공합니다.root(a=a(b=123, c='Hello, World!'), d=[1, 2, 3], e=[e_0(f='', g=None), e_1(f='Foo', g='Bar'), e_2(h='Hi!', i=None)], j=456, k=None)
형식을 지정하면 다음과 같습니다.
root(
a=a(
b=123,
c='Hello, World!'
),
d=[1, 2, 3],
e=[
e_0(
f='',
g=None
),
e_1(
f='Foo',
g='Bar'
),
e_2(
h='Hi!',
i=None
)
],
j=456,
k=None
)
또한 다른 개체처럼 중첩된 필드에 액세스할 수 있습니다.
print(x.a.b) # Prints: 123
이 경우 코드는 다음과 같습니다.
import yaml
with open(file_path, "r") as stream:
nested_dict = yaml.safe_load(stream)
nested_objt = Dict2ObjParser(nested_dict).parse()
이것이 도움이 되길 바랍니다!
다음은 사용자가 가상 환경(또는 시스템)에서 선택한 YAML 구현을 테스트한 다음 정의하는 한 가지 방법입니다.load_yaml_file
적절한:
load_yaml_file = None
if not load_yaml_file:
try:
import yaml
load_yaml_file = lambda fn: yaml.load(open(fn))
except:
pass
if not load_yaml_file:
import commands, json
if commands.getstatusoutput('ruby --version')[0] == 0:
def load_yaml_file(fn):
ruby = "puts YAML.load_file('%s').to_json" % fn
j = commands.getstatusoutput('ruby -ryaml -rjson -e "%s"' % ruby)
return json.loads(j[1])
if not load_yaml_file:
import os, sys
print """
ERROR: %s requires ruby or python-yaml to be installed.
apt-get install ruby
OR
apt-get install python-yaml
OR
Demonstrate your mastery of Python by using pip.
Please research the latest pip-based install steps for python-yaml.
Usually something like this works:
apt-get install epel-release
apt-get install python-pip
apt-get install libyaml-cpp-dev
python2.7 /usr/bin/pip install pyyaml
Notes:
Non-base library (yaml) should never be installed outside a virtualenv.
"pip install" is permanent:
https://stackoverflow.com/questions/1550226/python-setup-py-uninstall
Beware when using pip within an aptitude or RPM script.
Pip might not play by all the rules.
Your installation may be permanent.
Ruby is 7X faster at loading large YAML files.
pip could ruin your life.
https://stackoverflow.com/questions/46326059/
https://stackoverflow.com/questions/36410756/
https://stackoverflow.com/questions/8022240/
Never use PyYaml in numerical applications.
https://stackoverflow.com/questions/30458977/
If you are working for a Fortune 500 company, your choices are
1. Ask for either the "ruby" package or the "python-yaml"
package. Asking for Ruby is more likely to get a fast answer.
2. Work in a VM. I highly recommend Vagrant for setting it up.
""" % sys.argv[0]
os._exit(4)
# test
import sys
print load_yaml_file(sys.argv[1])
언급URL : https://stackoverflow.com/questions/6866600/how-to-parse-read-a-yaml-file-into-a-python-object
'source' 카테고리의 다른 글
PowerShell 스크립트를 깃 후크로 실행 (0) | 2023.08.05 |
---|---|
iPhone UITableView 스크롤 성능을 향상시키는 비결은 무엇입니까? (0) | 2023.08.05 |
null 가능한 열을 사용하여 MySQL 테이블을 조인하는 방법은 무엇입니까? (0) | 2023.08.05 |
DB(Hibernate 및 Oracle 10g)에서 동일한 행을 읽는 두 개의 서로 다른 스레드를 방지하는 방법 (0) | 2023.08.05 |
내가 내 스프링 API에 게시하려고 할 때 403 금지? (0) | 2023.08.05 |