PyYAML文档

PyYAML现在维护在https://github.com/yaml/pyyaml此页面仅用于历史目的。

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

安装

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

$ python setup.py install

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

$ python setup.py --with-libyaml install

为了使用基于LibYAML的解析器和发射器,使用类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和基于LibYAML的解析器和发射器之间存在一些细微差别(但不是真正重要的)差异

经常问的问题

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

为什么

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

a: 1
b: {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 Olleander
race: Human
traits: [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']))!Monster
ac: 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语法的一个很好的介绍是YAML规范的第2章

你也可以检查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标签在http://yaml.org/type/index.html定义

标签可能是隐含的:

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 data

add_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 node

add_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)添加了一个基于路径的隐式标签解析器。A 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 token

StreamStartToken(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 event

StreamStartEvent()

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语言编写的上述类别的版本LibYAML库。

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语言编写的上述类别的版本LibYAML库。

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}