Pertanyaan YAML parsing dan Python?


Apa cara terbaik untuk mem-parsing file YAML menjadi objek Python?

Misalnya, YAML ini:

Person:
  name: XYZ

Untuk kelas Python ini:

class Person(yaml.YAMLObject):
  yaml_tag = 'Person'

  def __init__(self, name):
    self.name = name

Saya menggunakan PyYAML dengan cara.


75
2017-07-28 22:36


asal


Jawaban:


Jika file YAML Anda terlihat seperti ini:

# tree format
treeroot:
    branch1:
        name: Node 1
        branch1-1:
            name: Node 1-1
    branch2:
        name: Node 2
        branch2-1:
            name: Node 2-1

Dan Anda sudah menginstal PyYAML seperti ini:

pip install PyYAML

Dan kode Python terlihat seperti ini:

import yaml
with open('tree.yaml') as f:
    # use safe_load instead load
    dataMap = yaml.safe_load(f)

Variabel dataMap sekarang berisi kamus dengan data pohon. Jika Anda mencetak dataMap menggunakan PrettyPrint, Anda akan mendapatkan sesuatu seperti:

{'treeroot': {'branch1': {'branch1-1': {'name': 'Node 1-1'},
    'name': 'Node 1'},
    'branch2': {'branch2-1': {'name': 'Node 2-1'},
    'name': 'Node 2'}}}

Jadi, sekarang kita telah melihat cara mendapatkan data ke dalam program Python kami. Menyimpan data sama mudahnya:

with open('newtree.yaml', "w") as f:
    yaml.dump(dataMap, f)

Anda memiliki kamus, dan sekarang Anda harus mengonversinya menjadi objek Python:

class Struct:
    def __init__(self, **entries): 
        self.__dict__.update(entries)

Maka Anda dapat menggunakan:

>>> args = your YAML dictionary
>>> s = Struct(**args)
>>> s
<__main__.Struct instance at 0x01D6A738>
>>> s...

dan ikuti "Konversi didik Python menjadi objek".

Untuk informasi lebih lanjut Anda dapat melihat pyyaml.org dan ini.


149
2017-07-28 22:49



Dari http://pyyaml.org/wiki/PyYAMLDocumentation:

add_path_resolver(tag, path, kind) menambahkan resolver tag implisit berbasis path. Jalur adalah daftar kunci yang membentuk jalur ke node di grafik representasi. Elemen jalur dapat berupa nilai string, bilangan bulat, atau Tidak ada. Jenis dari suatu node dapat berupa str, list, dict, atau 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

6
2018-02-07 15:32



Berikut ini adalah salah satu cara untuk menguji implementasi YAML yang telah dipilih pengguna pada virtualenv (atau sistem) dan kemudian definisikan load_yaml_file dengan tepat:

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])

0
2017-09-18 20:06