博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
PyYAML中文文档
阅读量:5924 次
发布时间:2019-06-19

本文共 32007 字,大约阅读时间需要 106 分钟。

PyYAML文档

PyYAML现在维护在此页面仅用于历史目的。

英文文档链接:http://pyyaml.org/wiki/PyYAMLDocumentation

安装

下载源码包PyYAML-3.12.tar.gz并解压缩。转到目录PyYAML-3.12并运行

$ python setup.py install

如果要使用比纯Python版本快得多的LibYAML绑定,则需要下载并安装然后你可以通过执行来构建和安装绑定

$ python setup.py --with-libyaml install

为了使用基于的解析器和发射器,使用类CParserCEmitter例如,

from yaml import load, dumptry:from yaml import CLoader as Loader, CDumper as Dumperexcept ImportError:from yaml import Loader, Dumper# ...data = load(stream, Loader=Loader)# ...output = dump(data, Dumper=Dumper)

请注意,纯Python和基于的解析器和发射器之间存在一些细微差别(但不是真正重要的)差异

经常问的问题

没有嵌套集合的字典不能正确转储

为什么

import yamldocument = """  a: 1  b:    c: 3    d: 4"""print yaml.dump(yaml.load(document))

a: 1b: {c: 3, d: 4}

(见#18,#24)?

这是一个正确的输出,尽管嵌套映射的风格是不同的。

默认情况下,PyYAML根据是否有嵌套集合来选择集合的样式。如果一个集合有嵌套的集合,它将被分配块的样式。否则就会有流动风格。

如果你想收藏到块样式总是被序列,设置参数default_flow_styledump()False例如,

>>> print yaml.dump(yaml.load(document), default_flow_style=False)a: 1b:  c: 3  d: 4

Python 3的支持

3.08版本开始,PyYAML和LibYAML绑定为Python 3提供了完整的支持。这是Python 2和Python 3版本之间PyYAML API差异的简要概述。

在Python 2中:

  • str对象被转换成!!str!!python/str!binary根据对象是否是一个ASCII,UTF-8或二进制字符串节点。

  • unicode对象根据对象是否是ASCII字符串被转换为!!python/unicode!!str节点。

  • yaml.dump(data)将该文档生成为UTF-8编码str对象。

  • yaml.dump(data, encoding=('utf-8'|'utf-16-be'|'utf-16-le'))str以指定的编码生成一个对象。

  • yaml.dump(data, encoding=None)产生一个unicode对象。

在Python 3中:

  • str对象被转换为!!str节点。

  • bytes对象被转换为!!binary节点。

  • 由于兼容性的原因,!!python/str!python/unicode标签仍然支持和相应的节点转换为str对象。

  • yaml.dump(data)生成文档作为str对象。

  • yaml.dump(data, encoding=('utf-8'|'utf-16-be'|'utf-16-le'))bytes以指定的编码生成一个对象。

教程

从导入yaml开始

>>> import yaml

加载YAML

警告:yaml.load从任何不受信任的来源收到任何数据都是不安全的yaml.load是一样强大的pickle.load,所以可以调用任何Python函数。yaml.safe_load虽然检查功能。

该函数yaml.load将YAML文档转换为Python对象。

>>> yaml.load("""... - Hesperiidae... - Papilionidae... - Apatelodidae... - Epiplemidae... """)['Hesperiidae', 'Papilionidae', 'Apatelodidae', 'Epiplemidae']

yaml.load接受一个字节字符串,一个Unicode字符串,一个打开的二进制文件对象或一个打开的文本文件对象。字节字符串或文件必须使用utf-8utf-16-beutf-16-le编码进行编码。yaml.load通过检查字符串/文件开始处BOM(字节顺序标记)序列来检测编码如果不存在BOM则假定utf-8编码。

yaml.load 返回一个Python对象。

>>> yaml.load(u"""... hello: Привет!... """)    # In Python 3, do not use the 'u' prefix{'hello': u'\u041f\u0440\u0438\u0432\u0435\u0442!'}>>> stream = file('document.yaml', 'r')    # 'document.yaml' contains a single YAML document.>>> yaml.load(stream)[...]    # A Python object corresponding to the document.

如果字符串或文件包含多个文档,则可以使用该yaml.load_all函数加载它们

>>> documents = """... ---... name: The Set of Gauntlets 'Pauraegen'... description: >...     A set of handgear with sparks that crackle...     across its knuckleguards.... ---... name: The Set of Gauntlets 'Paurnen'... description: >...   A set of gauntlets that gives off a foul,...   acrid odour yet remains untarnished.... ---... name: The Set of Gauntlets 'Paurnimmen'... description: >...   A set of handgear, freezing with unnatural cold.... """>>> for data in yaml.load_all(documents):...     print data{'description': 'A set of handgear with sparks that crackle across its knuckleguards.\n','name': "The Set of Gauntlets 'Pauraegen'"}{'description': 'A set of gauntlets that gives off a foul, acrid odour yet remains untarnished.\n','name': "The Set of Gauntlets 'Paurnen'"}{'description': 'A set of handgear, freezing with unnatural cold.\n','name': "The Set of Gauntlets 'Paurnimmen'"}

PyYAML允许你构造任何类型的Python对象。

>>> yaml.load("""... none: [~, null]... bool: [true, false, on, off]... int: 42... float: 3.14159... list: [LITE, RES_ACID, SUS_DEXT]... dict: {hp: 13, sp: 5}... """){'none': [None, None], 'int': 42, 'float': 3.1415899999999999,'list': ['LITE', 'RES_ACID', 'SUS_DEXT'], 'dict': {'hp': 13, 'sp': 5},'bool': [True, False, True, False]}

即使Python类的实例也可以使用!!python/object标签构造

>>> class Hero:...     def __init__(self, name, hp, sp):...         self.name = name...         self.hp = hp...         self.sp = sp...     def __repr__(self):...         return "%s(name=%r, hp=%r, sp=%r)" % (...             self.__class__.__name__, self.name, self.hp, self.sp)>>> yaml.load("""... !!python/object:__main__.Hero... name: Welthyr Syxgon... hp: 1200... sp: 0... """)Hero(name='Welthyr Syxgon', hp=1200, sp=0)

请注意,如果从不受信任的源(如Internet)接收到YAML文档,则构建任意Python对象的功能可能很危险。该函数yaml.safe_load将这种功能限制在简单的Python对象(如整数或列表)上。

一个python对象可以被标记为安全的,从而被识别yaml.safe_load为此,从yaml.YAMLObject(如构造函数,表示者,解析器部分中所解释的)中派生它并明确地将其类属性设置yaml_loaderyaml.SafeLoader

倾销YAML

yaml.dump函数接受一个Python对象并产生一个YAML文档。

>>> print yaml.dump({'name': 'Silenthand Olleander', 'race': 'Human',... 'traits': ['ONE_HAND', 'ONE_EYE']})name: Silenthand Olleanderrace: Humantraits: [ONE_HAND, ONE_EYE]

yaml.dump接受第二个可选参数,该参数必须是开放文本或二进制文件。在这种情况下,yaml.dump将生成的YAML文件写入文件。否则,yaml.dump返回生成的文件。

>>> stream = file('document.yaml', 'w')>>> yaml.dump(data, stream)    # Write a YAML representation of data to 'document.yaml'.>>> print yaml.dump(data)      # Output the document to the screen.

如果您需要将多个YAML文档转储到单个流,请使用该功能yaml.dump_allyaml.dump_all接受一个列表或一个生成器

将Python对象序列化成YAML文档。第二个可选参数是一个打开的文件。

>>> print yaml.dump([1,2,3], explicit_start=True)--- [1, 2, 3]>>> print yaml.dump_all([1,2,3], explicit_start=True)--- 1--- 2--- 3

你甚至可以转储Python类的实例。

>>> class Hero:...     def __init__(self, name, hp, sp):...         self.name = name...         self.hp = hp...         self.sp = sp...     def __repr__(self):...         return "%s(name=%r, hp=%r, sp=%r)" % (...             self.__class__.__name__, self.name, self.hp, self.sp)>>> print yaml.dump(Hero("Galain Ysseleg", hp=-3, sp=2))!!python/object:__main__.Hero {hp: -3, name: Galain Ysseleg, sp: 2}

yaml.dump支持一些指定发射器格式细节的关键字参数。例如,您可以设置首选的intendation和width,使用规范的YAML格式或强制首选样式作为标量和集合。

>>> print yaml.dump(range(50))[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,  23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,  43, 44, 45, 46, 47, 48, 49]>>> print yaml.dump(range(50), width=50, indent=4)[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,40, 41, 42, 43, 44, 45, 46, 47, 48, 49]>>> print yaml.dump(range(5), canonical=True)---!!seq [  !!int "0",  !!int "1",  !!int "2",  !!int "3",  !!int "4",]>>> print yaml.dump(range(5), default_flow_style=False)- 0- 1- 2- 3- 4>>> print yaml.dump(range(5), default_flow_style=True, default_style='"')[!!int "0", !!int "1", !!int "2", !!int "3", !!int "4"]

构造者,代表者,解析者

您可以定义您自己的应用程序特定的标签。最简单的方法是定义一个子类yaml.YAMLObject

>>> class Monster(yaml.YAMLObject):...     yaml_tag = u'!Monster'...     def __init__(self, name, hp, ac, attacks):...         self.name = name...         self.hp = hp...         self.ac = ac...         self.attacks = attacks...     def __repr__(self):...         return "%s(name=%r, hp=%r, ac=%r, attacks=%r)" % (...             self.__class__.__name__, self.name, self.hp, self.ac, self.attacks)

上面的定义足以自动加载和转储Monster对象:

>>> yaml.load("""... --- !Monster... name: Cave spider... hp: [2,6]    # 2d6... ac: 16... attacks: [BITE, HURT]... """)Monster(name='Cave spider', hp=[2, 6], ac=16, attacks=['BITE', 'HURT'])>>> print yaml.dump(Monster(...     name='Cave lizard', hp=[3,6], ac=16, attacks=['BITE','HURT']))!Monsterac: 16attacks: [BITE, HURT]hp: [3, 6]name: Cave lizard

yaml.YAMLObject 使用元类魔术来注册构造函数,该构造函数将YAML节点转换为类实例,以及将类实例序列化到YAML节点的表示器。

如果你不想使用元类,你可以使用函数yaml.add_constructor注册你的构造函数和表示者yaml.add_representer例如,您可能需要为以下Dice添加构造函数和表示符:

>>> class Dice(tuple):...     def __new__(cls, a, b):...         return tuple.__new__(cls, [a, b])...     def __repr__(self):...         return "Dice(%s,%s)" % self>>> print Dice(3,6)Dice(3,6)

Dice对象的默认表示形式不是很漂亮:

>>> print yaml.dump(Dice(3,6))!!python/object/new:__main__.Dice- !!python/tuple [3, 6]

假设你想要一个Dice对象AdB在YAML中表示

>>> print yaml.dump(Dice(3,6))3d6

首先,我们定义一个代表者,将一个骰子对象转换为一个标量节点!dice,然后注册它。

>>> def dice_representer(dumper, data):...     return dumper.represent_scalar(u'!dice', u'%sd%s' % data)>>> yaml.add_representer(Dice, dice_representer)

现在你可以转储一个Dice对象的实例

>>> print yaml.dump({'gold': Dice(10,6)}){gold: !dice '10d6'}

让我们添加代码来构建一个Dice对象:

>>> def dice_constructor(loader, node):...     value = loader.construct_scalar(node)...     a, b = map(int, value.split('d'))...     return Dice(a, b)>>> yaml.add_constructor(u'!dice', dice_constructor)

那么你也可以加载一个Dice对象:

>>> print yaml.load("""... initial hit points: !dice 8d4... """){'initial hit points': Dice(8,4)}

你可能不想在!dice任何地方指定标签有一种方法可以教PyYAML,看起来像XdY的任何未加标签的纯标量都有隐式标签!dice用途add_implicit_resolver

>>> import re>>> pattern = re.compile(r'^\d+d\d+$')>>> yaml.add_implicit_resolver(u'!dice', pattern)

现在,您不必指定标签来定义Dice对象:

>>> print yaml.dump({'treasure': Dice(10,20)}){treasure: 10d20}>>> print yaml.load("""... damage: 5d10... """){'damage': Dice(5,10)}

YAML语法

YAML语法的一个很好的介绍是

你也可以检查请注意,它专注于Ruby实现,并使用旧的YAML 1.0语法。

在这里,我们介绍最常见的YAML结构和相应的Python对象。

文件

YAML流是零个或多个文档的集合。一个空的流不包含任何文档。文件分开---文件可以有选择地结束...单个文档可能被标记或可能不被标记---

隐式文档的示例:

- Multimedia- Internet- Education

明确的文件的例子:

---- Afterstep- CTWM- Oroborus...

同一个流中的几个文档的示例:

---- Ada- APL- ASP- Assembly- Awk---- Basic---- C- C#    # Note that comments are denoted with ' #' (space then #).- C++- Cold Fusion

块序列

在块上下文中,序列条目用-(破折号然后空格)表示:

# YAML- The Dagger 'Narthanc'- The Dagger 'Nimthanc'- The Dagger 'Dethanc'
# Python["The Dagger 'Narthanc'", "The Dagger 'Nimthanc'", "The Dagger 'Dethanc'"]

块序列可以嵌套:

# YAML-  - HTML  - LaTeX  - SGML  - VRML  - XML  - YAML-  - BSD  - GNU Hurd  - Linux
# Python[['HTML', 'LaTeX', 'SGML', 'VRML', 'XML', 'YAML'], ['BSD', 'GNU Hurd', 'Linux']]

不需要用新行开始嵌套序列:

# YAML- 1.1- - 2.1  - 2.2- - - 3.1- 3.2- 3.3
# Python[1.1, [2.1, 2.2], [[3.1, 3.2, 3.3]]]

块序列可嵌套到块映射。请注意,在这种情况下,不需要缩进序列。

# YAMLleft hand:- Ring of Teleportation- Ring of Speedright hand:- Ring of Resist Fire- Ring of Resist Cold- Ring of Resist Poison
# Python{'right hand': ['Ring of Resist Fire', 'Ring of Resist Cold', 'Ring of Resist Poison'],'left hand': ['Ring of Teleportation', 'Ring of Speed']}

块映射

在块上下文中,映射的键和值由:(空格然后是空格)分隔开来

# YAMLbase armor class: 0base damage: [4,4]plus to-hit: 12plus to-dam: 16plus to-ac: 0
# Python{'plus to-hit': 12, 'base damage': [4, 4], 'base armor class': 0, 'plus to-ac': 0, 'plus to-dam': 16}

复杂键用?(问号然后空格)表示:

# YAML? !!python/tuple [0,0]: The Hero? !!python/tuple [0,1]: Treasure? !!python/tuple [1,0]: Treasure? !!python/tuple [1,1]: The Dragon
# Python{(0, 1): 'Treasure', (1, 0): 'Treasure', (0, 0): 'The Hero', (1, 1): 'The Dragon'}

块映射可以嵌套:

# YAMLhero:  hp: 34  sp: 8  level: 4orc:  hp: 12  sp: 0  level: 2
# Python{'hero': {'hp': 34, 'sp': 8, 'level': 4}, 'orc': {'hp': 12, 'sp': 0, 'level': 2}}

块映射可以嵌套在块序列中:

# YAML- name: PyYAML  status: 4  license: MIT  language: Python- name: PySyck  status: 5  license: BSD  language: Python
# Python[{'status': 4, 'language': 'Python', 'name': 'PyYAML', 'license': 'MIT'},{'status': 5, 'license': 'BSD', 'name': 'PySyck', 'language': 'Python'}]

流量收集

YAML中的流集合的语法非常接近Python中的列表和字典构造函数的语法:

# YAML{ str: [15, 17], con: [16, 16], dex: [17, 18], wis: [16, 16], int: [10, 13], chr: [5, 8] }
# Python{'dex': [17, 18], 'int': [10, 13], 'chr': [5, 8], 'wis': [16, 16], 'str': [15, 17], 'con': [16, 16]}

标量

YAML中有5种标量样式:简单,单引号,双引号,文字和折叠:

# YAMLplain: Scroll of Remove Cursesingle-quoted: 'EASY_KNOW'double-quoted: "?"literal: |    # Borrowed from http://www.kersbergen.com/flump/religion.html  by hjw              ___     __              /.-.\    /  )_____________\\  Y   /_ /=== == === === =\ _\_  ( /)=== == === === == Y   \   `-------------------(  o  )                        \___/folded: >  It removes all ordinary curses from all equipped items.  Heavy or permanent curses are unaffected.
# Python{'plain': 'Scroll of Remove Curse','literal':'by hjw              ___\n''   __              /.-.\\\n''  /  )_____________\\\\  Y\n'' /_ /=== == === === =\\ _\\_\n''( /)=== == === === == Y   \\\n'' `-------------------(  o  )\n''                      \\___/\n','single-quoted': 'EASY_KNOW','double-quoted': '?','folded': 'It removes all ordinary curses from all equipped items. Heavy or permanent curses are unaffected.\n'}

每种风格都有自己的怪癖。一个简单的标量不使用指标来表示它的开始和结束,因此它是最受限制的风格。它的自然应用是属性和参数的名称。

使用单引号标量,可以表示任何不包含特殊字符的值。除了一对相邻的引号''替换为一个单引号外,不会出现单引号标量的转义'

双引号是最强大的风格和唯一可以表达任何标量值的风格。双引号标量允许转义使用转义序列\x*\u***,你可以表达任何ASCII或Unicode字符。

有两种块标量样式:文字折叠字面风格是大块文本(如源代码)最适合的风格。折叠样式类似于文字样式,但两个相邻的非空行连接到由空格字符分隔的单个行。

别名

请注意,PyYAML还不支持递归对象。

使用YAML,您可以表示任意图形结构的对象。如果要从文档的不同部分引用同一个对象,则需要使用锚点和别名。

锚点由&指标表示,而别名用``表示。例如,文件

left hand: &A  name: The Bastard Sword of Eowyn  weight: 30right hand: *A

表达了英雄双手握着重剑的想法。

PyYAML现在完全支持递归对象。例如,文件

&A [ *A ]

会产生一个包含对自身引用的列表对象。

标签

标签用于表示YAML节点的类型。标准的YAML标签在定义

标签可能是隐含的:

boolean: trueinteger: 3float: 3.14
{'boolean': True, 'integer': 3, 'float': 3.14}

或明确的:

boolean: !!bool "true"integer: !!int "3"float: !!float "3.14"
{'boolean': True, 'integer': 3, 'float': 3.14}

没有明确定义的标记的纯标量将受到隐式标记解析的影响。标量值将根据一组正则表达式进行检查,如果其中一个匹配,则将相应的标记分配给标量。PyYAML允许应用程序添加自定义隐式标签解析器。

YAML标签和Python类型

下表介绍了具有不同标记的节点如何转换为Python对象。

YAML标签 Python类型
标准的YAML标签
!!null None
!!bool bool
!!int int或者longint在Python 3中)
!!float float
!!binary strbytes在Python 3中)
!!timestamp datetime.datetime
!!omap, !!pairs list 对
!!set set
!!str str或者unicodestr在Python 3中)
!!seq list
!!map dict
Python特定的标签
!!python/none None
!!python/bool bool
!!python/bytes bytes在Python 3中)
!!python/str strstr在Python 3中)
!!python/unicode unicodestr在Python 3中)
!!python/int int
!!python/long longint在Python 3中)
!!python/float float
!!python/complex complex
!!python/list list
!!python/tuple tuple
!!python/dict dict
复杂的Python标签
!!python/name:module.name module.name
!!python/module:package.module package.module
!!python/object:module.cls module.cls 例
!!python/object/new:module.cls module.cls 例
!!python/object/apply:module.f 的价值 f(...)

字符串转换(仅限Python 2)

有迹象表明,转换到四个标签strunicode值:!!str!!binary!!python/str,和!!python/unicode

!!strstr如果它的值是ASCII,标记的标量将被转换为对象否则,它被转换为unicode!!binary标记的标量被转换为str对象,其值使用base64编码进行解码。!!python/str标量转换为strutf-8编码编码的对象!!python/unicode标量转换为unicode对象。

相反,如果一个str对象!!str的值是ASCII,则它将被转换为一个标量2. !!python/str如果它的值是正确的utf-8序列,则为标量3.另一个!!binary标量。

如果unicode对象!!python/unicode的值是ASCII,对象将转换为1. 标量2.另一个!!str标量。

字符串转换(仅限Python 3)

在Python 3中,str对象被转换为!!str标量和bytes对象为!!binary标量。出于兼容性考虑,标签!!python/str!!python/unicode仍然支持并转换为str对象。

名称和模块

为了表示像函数或类的静态Python对象,你需要使用一个复杂的!!python/name标签。例如,该函数yaml.dump可以表示为

!!python/name:yaml.dump

同样,模块使用标签来表示!python/module

!!python/module:yaml

对象

任何pickleable对象可以使用!!python/object标签序列化

!!python/object:module.Class { attribute: value, ... }

为了支持泡菜协议,提供了另外两种形式的!!python/object标签:

!!python/object/new:module.Classargs: [argument, ...]kwds: {key: value, ...}state: ...listitems: [item, ...]dictitems: [key: value, ...]!!python/object/apply:module.functionargs: [argument, ...]kwds: {key: value, ...}state: ...listitems: [item, ...]dictitems: [key: value, ...]

如果只有该args字段非空,则可以缩短上述记录:

!!python/object/new:module.Class [argument, ...]!!python/object/apply:module.function [argument, ...]

参考

警告:API稳定性不能保证!

yaml包

scan(stream, Loader=Loader)

scan(stream)扫描给定stream并产生一个令牌序列。

parse(stream, Loader=Loader)emit(events, stream=None, Dumper=Dumper,    canonical=None,    indent=None,    width=None,    allow_unicode=None,    line_break=None)

parse(stream)解析给定的stream并产生一系列解析事件。

emit(events, stream=None)序列化给定的解析序列events并将它们写入stream如果streamNone,则返回生成的流。

compose(stream, Loader=Loader)compose_all(stream, Loader=Loader)serialize(node, stream=None, Dumper=Dumper,    encoding='utf-8', # encoding=None (Python 3)explicit_start=None,    explicit_end=None,    version=None,    tags=None,    canonical=None,    indent=None,    width=None,    allow_unicode=None,    line_break=None)serialize_all(nodes, stream=None, Dumper=Dumper, ...)

compose(stream)解析给定值stream并返回流中第一个文档的表示图的根。如果流中没有文档,则返回None

compose_all(stream)解析给定的stream并返回与流中文档相对应的一系列表示图。

serialize(node, stream=None)将给定的表示图形序列化为stream如果streamNone,则返回生成的流。

serialize_all(node, stream=None)将给定的表示图的序列序列化为给定的stream如果streamNone,则返回生成的流。

load(stream, Loader=Loader)load_all(stream, Loader=Loader)safe_load(stream)safe_load_all(stream)dump(data, stream=None, Dumper=Dumper,    default_style=None,    default_flow_style=None,    encoding='utf-8', # encoding=None (Python 3)explicit_start=None,    explicit_end=None,    version=None,    tags=None,    canonical=None,    indent=None,    width=None,    allow_unicode=None,    line_break=None)dump_all(data, stream=None, Dumper=Dumper, ...)safe_dump(data, stream=None, ...)safe_dump_all(data, stream=None, ...)

load(stream)解析给定的stream并返回从流中第一个文档构造而来的Python对象。如果流中没有文档,则返回None

load_all(stream)解析给定的stream并返回与流中文档相对应的Python对象序列。

safe_load(stream)解析给定的stream并返回从流中第一个文档构造而来的Python对象。如果流中没有文档,则返回Nonesafe_load只识别标准的YAML标签,不能构造任意的Python对象。

一个python对象可以被标记为安全的,从而被识别yaml.safe_load为此,从yaml.YAMLObject(如构造函数,表示者,解析器部分中所解释的)中派生它并明确地将其类属性设置yaml_loaderyaml.SafeLoader

safe_load_all(stream)解析给定的stream并返回与流中文档相对应的Python对象序列。safe_load_all只识别标准的YAML标签,不能构造任意的Python对象。

dump(data, stream=None)将给定的Python对象序列化为stream如果streamNone,则返回生成的流。

dump_all(data, stream=None)将给定的Python对象序列序列化为给定的stream如果streamNone,则返回生成的流。每个对象都被表示为一个YAML文档。

safe_dump(data, stream=None)将给定的Python对象序列化为stream如果streamNone,则返回生成的流。safe_dump只产生标准的YAML标签,不能表示一个任意的Python对象。

safe_dump_all(data, stream=None)将给定的Python对象序列序列化为给定的stream如果streamNone,则返回生成的流。每个对象都被表示为一个YAML文档。safe_dump_all只产生标准的YAML标签,不能表示一个任意的Python对象。

def constructor(loader, node):# ...return datadef multi_constructor(loader, tag_suffix, node):# ...return dataadd_constructor(tag, constructor, Loader=Loader)add_multi_constructor(tag_prefix, multi_constructor, Loader=Loader)

add_constructor(tag, constructor)指定一个constructor给定的tag构造函数是将YAML表示图的节点转换为本地Python对象的函数。构造函数接受Loader一个节点的实例并返回一个Python对象。

add_multi_constructor(tag_prefix, multi_constructor)指定一个multi_constructor给定的tag_prefix多构造函数是将YAML表示图的节点转换为本地Python对象的函数。多构造器接受Loader节点标记的后缀和节点的实例,并返回一个Python对象。

def representer(dumper, data):# ...return nodedef multi_representer(dumper, data):# ...return nodeadd_representer(data_type, representer, Dumper=Dumper)add_multi_representer(base_data_type, multi_representer, Dumper=Dumper)

add_representer(data_type, representer)representer为给定的Python对象指定一个data_type代表者是将本地Python对象转换为YAML表示图的节点的函数。代表者接受一个实例Dumper和一个对象并返回一个节点。

add_multi_representer(base_data_type, multi_representer)指定multi_representer给定base_data_type或其任何子类的Python对象多表示器是将本地Python对象转换为YAML表示图的节点的函数。多表示者接受一个Dumper对象的实例并返回一个节点。

add_implicit_resolver(tag, regexp, first, Loader=Loader, Dumper=Dumper)add_path_resolver(tag, path, kind, Loader=Loader, Dumper=Dumper)

add_implicit_resolver(tag, regexp, first)为普通标量添加隐式标签解析器。如果标量值与给定值相匹配regexp,则分配tagfirst是可能的初始字符列表或None

add_path_resolver(tag, path, kind)添加了一个基于路径的隐式标签解析器。path是在表示图形中形成节点路径的键列表。路径元素可以是字符串值,整数或None所述kind的节点可以是strlistdict,或None

标记

Mark(name, index, line, column, buffer, pointer)

Mark指向输入流中某个位置的实例name是流的名称,例如,如果输入流是文件,则它可以是文件名。line并且column是该位置的行和列(从0开始)。buffer当它不是的时候None,是包含该位置的输入流的一部分,并且pointer指的是位置buffer

YAMLError

YAMLError()

如果YAML解析器遇到错误情况,则会引发一个异常,该异常是YAMLError其子类的一个实例应用程序可能会捕获此异常并警告用户。

try:    config = yaml.load(file('config.yaml', 'r'))except yaml.YAMLError, exc:print "Error in configuration file:", exc

YAML处理器产生的异常可能指向有问题的位置。

>>> try:...     yaml.load("unbalanced blackets: ][")... except yaml.YAMLError, exc:...     if hasattr(exc, 'problem_mark'):...         mark = exc.problem_mark...         print "Error position: (%s:%s)" % (mark.line+1, mark.column+1)Error position: (1:22)

令牌

令牌由YAML扫描仪生成。除了低级YAML应用程序(如语法突出显示)之外,它们并不是真正有用的。

PyYAML扫描器产生以下类型的标记:

StreamStartToken(encoding, start_mark, end_mark) # Start of the stream.StreamEndToken(start_mark, end_mark) # End of the stream.DirectiveToken(name, value, start_mark, end_mark) # YAML directive, either %YAML or %TAG.DocumentStartToken(start_mark, end_mark) # '---'.DocumentEndToken(start_mark, end_mark) # '...'.BlockSequenceStartToken(start_mark, end_mark) # Start of a new block sequence.BlockMappingStartToken(start_mark, end_mark) # Start of a new block mapping.BlockEndToken(start_mark, end_mark) # End of a block collection.FlowSequenceStartToken(start_mark, end_mark) # '['.FlowMappingStartToken(start_mark, end_mark) # '{'.FlowSequenceEndToken(start_mark, end_mark) # ']'.FlowMappingEndToken(start_mark, end_mark) # '}'.KeyToken(start_mark, end_mark) # Either '?' or start of a simple key.ValueToken(start_mark, end_mark) # ':'.BlockEntryToken(start_mark, end_mark) # '-'.FlowEntryToken(start_mark, end_mark) # ','.AliasToken(value, start_mark, end_mark) # '*value'.AnchorToken(value, start_mark, end_mark) # '&value'.TagToken(value, start_mark, end_mark) # '!value'.ScalarToken(value, plain, style, start_mark, end_mark) # 'value'.

start_markend_mark表示令牌的开始和结束。

例:

>>> document = """... ---... block sequence:... - BlockEntryToken... block mapping:...   ? KeyToken...   : ValueToken... flow sequence: [FlowEntryToken, FlowEntryToken]... flow mapping: {KeyToken: ValueToken}... anchors and tags:... - &A !!int '5'... - *A... ...... """>>> for token in yaml.scan(document):...     print tokenStreamStartToken(encoding='utf-8')DocumentStartToken()BlockMappingStartToken()KeyToken()ScalarToken(plain=True, style=None, value=u'block sequence')ValueToken()BlockEntryToken()ScalarToken(plain=True, style=None, value=u'BlockEntryToken')KeyToken()ScalarToken(plain=True, style=None, value=u'block mapping')ValueToken()BlockMappingStartToken()KeyToken()ScalarToken(plain=True, style=None, value=u'KeyToken')ValueToken()ScalarToken(plain=True, style=None, value=u'ValueToken')BlockEndToken()KeyToken()ScalarToken(plain=True, style=None, value=u'flow sequence')ValueToken()FlowSequenceStartToken()ScalarToken(plain=True, style=None, value=u'FlowEntryToken')FlowEntryToken()ScalarToken(plain=True, style=None, value=u'FlowEntryToken')FlowSequenceEndToken()KeyToken()ScalarToken(plain=True, style=None, value=u'flow mapping')ValueToken()FlowMappingStartToken()KeyToken()ScalarToken(plain=True, style=None, value=u'KeyToken')ValueToken()ScalarToken(plain=True, style=None, value=u'ValueToken')FlowMappingEndToken()KeyToken()ScalarToken(plain=True, style=None, value=u'anchors and tags')ValueToken()BlockEntryToken()AnchorToken(value=u'A')TagToken(value=(u'!!', u'int'))ScalarToken(plain=False, style="'", value=u'5')BlockEntryToken()AliasToken(value=u'A')BlockEndToken()DocumentEndToken()StreamEndToken()

活动

事件由低级解析器和发射器接口使用,与SAX API类似。当解析器解析YAML流并产生一系列事件时,Emitter接受一系列事件并发出一个YAML流。

以下事件被定义:

StreamStartEvent(encoding, start_mark, end_mark)StreamEndEvent(start_mark, end_mark)DocumentStartEvent(explicit, version, tags, start_mark, end_mark)DocumentEndEvent(start_mark, end_mark)SequenceStartEvent(anchor, tag, implicit, flow_style, start_mark, end_mark)SequenceEndEvent(start_mark, end_mark)MappingStartEvent(anchor, tag, implicit, flow_style, start_mark, end_mark)MappingEndEvent(start_mark, end_mark)AliasEvent(anchor, start_mark, end_mark)ScalarEvent(anchor, tag, implicit, value, style, start_mark, end_mark)

flow_style标志指示集合是阻止还是流动。可能的值是NoneTrueFalsestyle标量事件标志表示标量的样式。可能的值是None_'\_'"''|''>'implicit收集开始事件标志指示在发射收集时是否可以省略标签。implicit标量事件标志是一对布尔值,表示当标量以相应的普通和非普通样式发射时标记是否可以省略。

例:

>>> document = """... scalar: &A !!int '5'... alias: *A... sequence: [1, 2, 3]... mapping: [1: one, 2: two, 3: three]... """>>> for event in yaml.parse(document):...     print eventStreamStartEvent()DocumentStartEvent()MappingStartEvent(anchor=None, tag=None, implicit=True)ScalarEvent(anchor=None, tag=None, implicit=(True, False), value=u'scalar')ScalarEvent(anchor=u'A', tag=u'tag:yaml.org,2002:int', implicit=(False, False), value=u'5')ScalarEvent(anchor=None, tag=None, implicit=(True, False), value=u'alias')AliasEvent(anchor=u'A')ScalarEvent(anchor=None, tag=None, implicit=(True, False), value=u'sequence')SequenceStartEvent(anchor=None, tag=None, implicit=True)ScalarEvent(anchor=None, tag=None, implicit=(True, False), value=u'1')ScalarEvent(anchor=None, tag=None, implicit=(True, False), value=u'2')ScalarEvent(anchor=None, tag=None, implicit=(True, False), value=u'3')SequenceEndEvent()ScalarEvent(anchor=None, tag=None, implicit=(True, False), value=u'mapping')MappingStartEvent(anchor=None, tag=None, implicit=True)ScalarEvent(anchor=None, tag=None, implicit=(True, False), value=u'1')ScalarEvent(anchor=None, tag=None, implicit=(True, False), value=u'one')ScalarEvent(anchor=None, tag=None, implicit=(True, False), value=u'2')ScalarEvent(anchor=None, tag=None, implicit=(True, False), value=u'two')ScalarEvent(anchor=None, tag=None, implicit=(True, False), value=u'3')ScalarEvent(anchor=None, tag=None, implicit=(True, False), value=u'three')MappingEndEvent()MappingEndEvent()DocumentEndEvent()StreamEndEvent()>>> print yaml.emit([...     yaml.StreamStartEvent(encoding='utf-8'),...     yaml.DocumentStartEvent(explicit=True),...     yaml.MappingStartEvent(anchor=None, tag=u'tag:yaml.org,2002:map', implicit=True, flow_style=False),...     yaml.ScalarEvent(anchor=None, tag=u'tag:yaml.org,2002:str', implicit=(True, True), value=u'agile languages'),...     yaml.SequenceStartEvent(anchor=None, tag=u'tag:yaml.org,2002:seq', implicit=True, flow_style=True),...     yaml.ScalarEvent(anchor=None, tag=u'tag:yaml.org,2002:str', implicit=(True, True), value=u'Python'),...     yaml.ScalarEvent(anchor=None, tag=u'tag:yaml.org,2002:str', implicit=(True, True), value=u'Perl'),...     yaml.ScalarEvent(anchor=None, tag=u'tag:yaml.org,2002:str', implicit=(True, True), value=u'Ruby'),...     yaml.SequenceEndEvent(),...     yaml.MappingEndEvent(),...     yaml.DocumentEndEvent(explicit=True),...     yaml.StreamEndEvent(),... ])---agile languages: [Python, Perl, Ruby]...

节点

节点是YAML信息模型中的实体。有三种节点:标量序列映射在PyYAML中,节点由Composer生成,可以通过Serializer序列化为YAML流。

ScalarNode(tag, value, style, start_mark, end_mark)SequenceNode(tag, value, flow_style, start_mark, end_mark)MappingNode(tag, value, flow_style, start_mark, end_mark)

styleflow_style标志的含义事件相同。标量节点的值必须是unicode字符串。序列节点的值是一个节点列表。映射节点的值是由键和值节点组成的一对列表。

例:

>>> print yaml.compose("""... kinds:... - scalar... - sequence... - mapping... """)MappingNode(tag=u'tag:yaml.org,2002:map', value=[    (ScalarNode(tag=u'tag:yaml.org,2002:str', value=u'kinds'), SequenceNode(tag=u'tag:yaml.org,2002:seq', value=[        ScalarNode(tag=u'tag:yaml.org,2002:str', value=u'scalar'),        ScalarNode(tag=u'tag:yaml.org,2002:str', value=u'sequence'),        ScalarNode(tag=u'tag:yaml.org,2002:str', value=u'mapping')]))])>>> print yaml.serialize(yaml.SequenceNode(tag=u'tag:yaml.org,2002:seq', value=[...     yaml.ScalarNode(tag=u'tag:yaml.org,2002:str', value=u'scalar'),...     yaml.ScalarNode(tag=u'tag:yaml.org,2002:str', value=u'sequence'),...     yaml.ScalarNode(tag=u'tag:yaml.org,2002:str', value=u'mapping')]))- scalar- sequence- mapping

装载机

Loader(stream)SafeLoader(stream)BaseLoader(stream)# The following classes are available only if you build LibYAML bindings.CLoader(stream)CSafeLoader(stream)CBaseLoader(stream)

Loader(stream)是上述类中最常见的,应该在大多数情况下使用。stream是一个输入YAML流。它可以是一个字符串,一个Unicode字符串,一个打开的文件,一个开放的Unicode文件。

Loader支持所有预定义的标签,可以构造一个任意的Python对象。因此,使用Loader从不受信任的来源加载文档是不安全的默认情况下,该功能scanparsecomposeconstruct,和其他人使用Loader

SafeLoader(stream)仅支持标准的YAML标签,因此它不会构造类实例,并且可能安全地使用从不可信源接收的文档。用于解析流的函数safe_loadsafe_load_all用法SafeLoader

BaseLoader(stream) 不解析或支持任何标签,只构造基本的Python对象:列表,字典和Unicode字符串。

CLoaderCSafeLoaderCBaseLoader是使用C语言编写的上述类别的版本库。

Loader.check_token(*TokenClasses)Loader.peek_token()Loader.get_token()

Loader.check_token(*TokenClasses)True如果流中的下一个标记是给定的其中一个实例,则返回TokenClasses否则它返回False

Loader.peek_token()返回流中的下一个标记,但不会将其从内部标记队列中删除。该函数返回None流的结尾。

Loader.get_token()返回流中的下一个标记,并将其从内部标记队列中删除。该函数返回None流的结尾。

Loader.check_event(*EventClasses)Loader.peek_event()Loader.get_event()

Loader.check_event(*EventClasses)True如果流中的下一个事件是给定的其中一个实例,则返回EventClasses否则它返回False

Loader.peek_event()返回流中的下一个事件,但不会将其从内部事件队列中删除。该函数返回None流的结尾。

Loader.get_event()返回流中的下一个事件,并将其从内部事件队列中移除。该函数返回None流的结尾。

Loader.check_node()Loader.get_node()

Loader.check_node()返回的True是流中有更多的文档可用。否则它返回False

Loader.get_node() 构造流中下一个文档的表示图并返回其根节点。

Loader.check_data()Loader.get_data()Loader.add_constructor(tag, constructor) # Loader.add_constructor is a class method.Loader.add_multi_constructor(tag_prefix, multi_constructor) # Loader.add_multi_constructor is a class method.Loader.construct_scalar(node)Loader.construct_sequence(node)Loader.construct_mapping(node)

Loader.check_data()返回的True是流中有更多的文档可用。否则它返回False

Loader.get_data() 构造并返回与流中下一个文档相对应的Python对象。

Loader.add_constructor(tag, constructor):看add_constructor

Loader.add_multi_constructor(tag_prefix, multi_constructor):看add_multi_constructor

Loader.construct_scalar(node)检查给定的node是一个标量并返回它的值。这个函数打算在构造函数中使用。

Loader.construct_sequence(node)检查给定的node是一个序列,并返回与节点项对应的Python对象列表。这个函数打算在构造函数中使用。

Loader.construct_mapping(node)检查给定的node是一个映射,并返回对应于节点键和值的Python对象的字典。这个函数打算在构造函数中使用。

Loader.add_implicit_resolver(tag, regexp, first) # Loader.add_implicit_resolver is a class method.Loader.add_path_resolver(tag, path, kind) # Loader.add_path_resolver is a class method.

Loader.add_implicit_resolver(tag, regexp, first):看add_implicit_resolver

Loader.add_path_resolver(tag, path, kind):看add_path_resolver

自卸车

Dumper(stream,    default_style=None,    default_flow_style=None,    canonical=None,    indent=None,    width=None,    allow_unicode=None,    line_break=None,    encoding=None,    explicit_start=None,    explicit_end=None,    version=None,    tags=None)SafeDumper(stream, ...)BaseDumper(stream, ...)# The following classes are available only if you build LibYAML bindings.CDumper(stream, ...)CSafeDumper(stream, ...)CBaseDumper(stream, ...)

Dumper(stream)是上述类中最常见的,应该在大多数情况下使用。stream是一个输出YAML流。它可以是一个开放的文件或一个开放的Unicode文件。

Dumper支持所有预定义的标签,可以代表一个任意的Python对象。因此它可能产生一个不能被其他YAML处理器加载的文档。默认情况下,该功能emitserializedump,和其他人使用Dumper

SafeDumper(stream)只生成标准的YAML标签,因此不能表示类实例,可能与其他YAML处理器更兼容。用于生成YAML文档的功能safe_dumpsafe_dump_all用途SafeDumper

BaseDumper(stream) 不支持任何标签,仅用于子类化。

CDumperCSafeDumperCBaseDumper是使用C语言编写的上述类别的版本库。

Dumper.emit(event)

Dumper.emit(event)将给定的序列化event并将其写入输出流。

Dumper.open()Dumper.serialize(node)Dumper.close()

Dumper.open()发出StreamStartEvent

Dumper.serialize(node) 将给定的表示图形串行化到输出流中。

Dumper.close()发出StreamEndEvent

Dumper.represent(data)Dumper.add_representer(data_type, representer) # Dumper.add_representer is a class method.Dumper.add_multi_representer(base_data_type, multi_representer) # Dumper.add_multi_representer is a class method.Dumper.represent_scalar(tag, value, style=None)Dumper.represent_sequence(tag, value, flow_style=None)Dumper.represent_mapping(tag, value, flow_style=None)

Dumper.represent(data) 将给定的Python对象序列化为输出YAML流。

Dumper.add_representer(data_type, representer):看add_representer

Dumper.add_multi_representer(base_data_type, multi_representer):看add_multi_representer

Dumper.represent_scalar(tag, value, style=None)返回给定标节点tagvaluestyle此功能旨在用于代表人员。

Dumper.represent_sequence(tag, sequence, flow_style=None)返回给定子节点和给定子tag节点所生成的子节点sequence

Dumper.represent_mapping(tag, mapping, flow_style=None)返回一个映射节点,其中给定子节点和给定子tag节点的值由给定子节点生成mapping

Dumper.add_implicit_resolver(tag, regexp, first) # Dumper.add_implicit_resolver is a class method.Dumper.add_path_resolver(tag, path, kind) # Dumper.add_path_resolver is a class method.

Dumper.add_implicit_resolver(tag, regexp, first):看add_implicit_resolver

Dumper.add_path_resolver(tag, path, kind):看add_path_resolver

YAMLObject

class MyYAMLObject(YAMLObject):    yaml_loader = Loader    yaml_dumper = Dumper    yaml_tag = u'...'yaml_flow_style = ...@classmethoddef from_yaml(cls, loader, node):# ...return data@classmethoddef to_yaml(cls, dumper, data):# ...return node

子类化YAMLObject是为定义标签,构造函数和表示的简单方法。您只需要覆盖该yaml_tag属性。如果要定义自定义构造函数和申述,重新定义from_yamlto_yaml方法相应。

偏离规范

需要更新本节

  • YAML中制表符的规则令人困惑。我们很近,但还没有。也许规范和解析器都应该被修复。无论如何,在YAML制表符的最好的规则是根本不使用它们。

  • 字节顺序标记。最初的BOM被剥离,但是流内的BOM被视为内容的一部分。它可以修复,但现在并不重要。

  • 如果指定了别名或标记,则不允许使用空纯标量。这样做是为了防止像[!tag,value]这样的异常,它可以解释为[!值][!“”,“价值”]规范应该是固定的。

  • 流收集的缩进。规范要求它们比块父节点缩进更多。不幸的是,这个规则使许多直观正确的构造无效,例如,

    block: {} # this is indentation violation according to the spec.
  • 流动模式下不允许使用“:”标记。 {1:2}被解释为{1:2}

     本文转自506554897 51CTO博客,原文链接:http://blog.51cto.com/506554897/1984140,如需转载请自行联系原作者

你可能感兴趣的文章
java虚拟机学习笔记 【1】
查看>>
DUBBO笔记
查看>>
scala基础续
查看>>
nginx php上传大文件的设置(php-fpm)
查看>>
MySQL 运行状态监控方法
查看>>
Fedora 12 环境下Gtk+开发环境配置
查看>>
vs2008中在解决方案资源管理器查看当前打开文件
查看>>
ubuntu14.04 鼠标闪烁问题
查看>>
jQuery Lightbox(balupton版)图片展示插件demo
查看>>
Elasticsearch集群的简单搭建
查看>>
SCRT-SSH传输文件
查看>>
VOA 26/02/2009 EDUCATION REPORT - Studying in the US: Web Redefines the College Visit
查看>>
缓冲池相关
查看>>
foxmail A message does not have receiver解决方法
查看>>
slidingMenu
查看>>
AngularJS之控制器
查看>>
PIC32多媒体开发板
查看>>
禁止搜索引擎转码方法
查看>>
l洛谷——P1211 [USACO1.3]牛式 Prime Cryptarithm
查看>>
域模式中批量创建用户
查看>>