PyYAML中文文档「建议收藏」

2022-09-27 11:37:42 浏览数 (1)

大家好,又见面了,我是你们的朋友全栈君

PyYAML文档

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

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

安装

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

代码语言:javascript复制
$ python setup.py install

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

代码语言:javascript复制
$ python setup.py --with-libyaml install

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

代码语言:javascript复制
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的解析器和发射器之间存在一些细微差别(但不是真正重要的)差异。

经常问的问题

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

为什么

代码语言:javascript复制
import yaml
document = """  a: 1  b:    c: 3    d: 4"""print yaml.dump(yaml.load(document))

代码语言:javascript复制
a: 1
b: {c: 3, d: 4}

(见#18,#24)?

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

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

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

代码语言:javascript复制
>>> 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包开始。

代码语言:javascript复制
>>> import yaml

加载YAML

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

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

代码语言:javascript复制
>>> 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对象。

代码语言:javascript复制
>>> yaml.load(u"""... hello: Привет!... """)    # In Python 3, do not use the 'u' prefix{'hello': u'u041fu0440u0438u0432u0435u0442!'}>>> 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函数加载它们。

代码语言:javascript复制
>>> 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对象。

代码语言:javascript复制
>>> 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标签构造。

代码语言:javascript复制
>>> 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文档。

代码语言:javascript复制
>>> 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返回生成的文件。

代码语言:javascript复制
>>> 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文档。第二个可选参数是一个打开的文件。

代码语言:javascript复制
>>> 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类的实例。

代码语言:javascript复制
>>> 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格式或强制首选样式作为标量和集合。

代码语言:javascript复制
>>> 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

代码语言:javascript复制
>>> 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对象:

代码语言:javascript复制
>>> 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类添加构造函数和表示符:

代码语言:javascript复制
>>> 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对象的默认表示形式不是很漂亮:

代码语言:javascript复制
>>> print yaml.dump(Dice(3,6))!!python/object/new:__main__.Dice- !!python/tuple [3, 6]

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

代码语言:javascript复制
>>> print yaml.dump(Dice(3,6))

3d6

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

代码语言:javascript复制
>>> def dice_representer(dumper, data):
...     return dumper.represent_scalar(u'!dice', u'%sd%s' % data)>>> yaml.add_representer(Dice, dice_representer)

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

代码语言:javascript复制
>>> print yaml.dump({'gold': Dice(10,6)})
{gold: !dice '10d6'}

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

代码语言:javascript复制
>>> 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对象:

代码语言:javascript复制
>>> print yaml.load("""... initial hit points: !dice 8d4... """)

{'initial hit points': Dice(8,4)}

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

代码语言:javascript复制
>>> import re>>> pattern = re.compile(r'^d dd $')>>> yaml.add_implicit_resolver(u'!dice', pattern)

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

代码语言:javascript复制
>>> 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流是零个或多个文档的集合。一个空的流不包含任何文档。文件分开---。文件可以有选择地结束...。单个文档可能被标记或可能不被标记---

隐式文档的示例:

代码语言:javascript复制
- Multimedia- Internet- Education

明确的文件的例子:

代码语言:javascript复制
---- Afterstep- CTWM- Oroborus...

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

代码语言:javascript复制
---- Ada- APL- ASP- Assembly- Awk---- Basic---- C- C#    # Note that comments are denoted with ' #' (space then #).- C  - Cold Fusion

块序列

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

代码语言:javascript复制
# YAML- The Dagger 'Narthanc'- The Dagger 'Nimthanc'- The Dagger 'Dethanc'
代码语言:javascript复制
# Python["The Dagger 'Narthanc'", "The Dagger 'Nimthanc'", "The Dagger 'Dethanc'"]

块序列可以嵌套:

代码语言:javascript复制
# YAML-
  - HTML  - LaTeX  - SGML  - VRML  - XML  - YAML-
  - BSD  - GNU Hurd  - Linux
代码语言:javascript复制
# Python[['HTML', 'LaTeX', 'SGML', 'VRML', 'XML', 'YAML'], ['BSD', 'GNU Hurd', 'Linux']]

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

代码语言:javascript复制
# YAML- 1.1- - 2.1  - 2.2- - - 3.1- 3.2- 3.3
代码语言:javascript复制
# Python[1.1, [2.1, 2.2], [[3.1, 3.2, 3.3]]]

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

代码语言:javascript复制
# YAMLleft hand:- Ring of Teleportation- Ring of Speedright hand:- Ring of Resist Fire- Ring of Resist Cold- Ring of Resist Poison
代码语言:javascript复制
# Python{'right hand': ['Ring of Resist Fire', 'Ring of Resist Cold', 'Ring of Resist Poison'],'left hand': ['Ring of Teleportation', 'Ring of Speed']}

块映射

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

代码语言:javascript复制
# YAMLbase armor class: 0base damage: [4,4]plus to-hit: 12plus to-dam: 16plus to-ac: 0
代码语言:javascript复制
# Python{'plus to-hit': 12, 'base damage': [4, 4], 'base armor class': 0, 'plus to-ac': 0, 'plus to-dam': 16}

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

代码语言:javascript复制
# YAML? !!python/tuple [0,0]: The Hero
? !!python/tuple [0,1]: Treasure
? !!python/tuple [1,0]: Treasure
? !!python/tuple [1,1]: The Dragon
代码语言:javascript复制
# Python{(0, 1): 'Treasure', (1, 0): 'Treasure', (0, 0): 'The Hero', (1, 1): 'The Dragon'}

块映射可以嵌套:

代码语言:javascript复制
# YAMLhero:
  hp: 34  sp: 8  level: 4orc:
  hp: 12  sp: 0  level: 2
代码语言:javascript复制
# Python{'hero': {'hp': 34, 'sp': 8, 'level': 4}, 'orc': {'hp': 12, 'sp': 0, 'level': 2}}

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

代码语言:javascript复制
# YAML- name: PyYAML  status: 4  license: MIT  language: Python- name: PySyck  status: 5  license: BSD  language: Python
代码语言:javascript复制
# Python[{'status': 4, 'language': 'Python', 'name': 'PyYAML', 'license': 'MIT'},
{'status': 5, 'license': 'BSD', 'name': 'PySyck', 'language': 'Python'}]

流量收集

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

代码语言:javascript复制
# YAML{ str: [15, 17], con: [16, 16], dex: [17, 18], wis: [16, 16], int: [10, 13], chr: [5, 8] }
代码语言:javascript复制
# Python{'dex': [17, 18], 'int': [10, 13], 'chr': [5, 8], 'wis': [16, 16], 'str': [15, 17], 'con': [16, 16]}

标量

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

代码语言:javascript复制
# 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.
代码语言:javascript复制
# Python{'plain': 'Scroll of Remove Curse','literal':'by hjw              ___n''   __              /.-.\n''  /  )_____________\\  Yn'' /_ /=== == === === =\ _\_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,您可以表示任意图形结构的对象。如果要从文档的不同部分引用同一个对象,则需要使用锚点和别名。

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

代码语言:javascript复制
left hand: &A
  name: The Bastard Sword of Eowyn  weight: 30right hand: *A

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

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

代码语言:javascript复制
&A [ *A ]

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

标签

标签用于表示YAML节点的类型。标准的YAML标签在http://yaml.org/type/index.html定义。

标签可能是隐含的:

代码语言:javascript复制
boolean: trueinteger: 3float: 3.14
代码语言:javascript复制
{'boolean': True, 'integer': 3, 'float': 3.14}

或明确的:

代码语言:javascript复制
boolean: !!bool "true"integer: !!int "3"float: !!float "3.14"
代码语言:javascript复制
{'boolean': True, 'integer': 3, 'float': 3.14}

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

YAML标签和Python类型

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

YAML标签

Python类型

标准的YAML标签

!!null

None

!!bool

bool

!!int

int或者long(int在Python 3中)

!!float

float

!!binary

str(bytes在Python 3中)

!!timestamp

datetime.datetime

!!omap, !!pairs

list 对

!!set

set

!!str

str或者unicode(str在Python 3中)

!!seq

list

!!map

dict

Python特定的标签

!!python/none

None

!!python/bool

bool

!!python/bytes

(bytes在Python 3中)

!!python/str

str(str在Python 3中)

!!python/unicode

unicode(str在Python 3中)

!!python/int

int

!!python/long

long(int在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可以表示为

代码语言:javascript复制
!!python/name:yaml.dump

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

代码语言:javascript复制
!!python/module:yaml

对象

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

代码语言:javascript复制
!!python/object:module.Class { attribute: value, ... }

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

代码语言:javascript复制
!!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字段非空,则可以缩短上述记录:

代码语言:javascript复制
!!python/object/new:module.Class [argument, ...]!!python/object/apply:module.function [argument, ...]

参考

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

yaml包

代码语言:javascript复制
scan(stream, Loader=Loader)

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

代码语言:javascript复制
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,则返回生成的流。

代码语言:javascript复制
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,则返回生成的流。

代码语言:javascript复制
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对象。

代码语言:javascript复制
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对象。

代码语言:javascript复制
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对象的实例并返回一个节点。

代码语言:javascript复制
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

标记

代码语言:javascript复制
Mark(name, index, line, column, buffer, pointer)

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

YAMLError

代码语言:javascript复制
YAMLError()

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

代码语言:javascript复制
try:
    config = yaml.load(file('config.yaml', 'r'))except yaml.YAMLError, exc:print "Error in configuration file:", exc

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

代码语言:javascript复制
>>> 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扫描器产生以下类型的标记:

代码语言:javascript复制
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表示令牌的开始和结束。

例:

代码语言:javascript复制
>>> 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流。

以下事件被定义:

代码语言:javascript复制
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标量事件的标志是一对布尔值,表示当标量以相应的普通和非普通样式发射时标记是否可以省略。

例:

代码语言:javascript复制
>>> 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流。

代码语言:javascript复制
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字符串。序列节点的值是一个节点列表。映射节点的值是由键和值节点组成的一对列表。

例:

代码语言:javascript复制
>>> 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

装载机

代码语言:javascript复制
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库。

代码语言:javascript复制
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流的结尾。

代码语言:javascript复制
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流的结尾。

代码语言:javascript复制
Loader.check_node()
Loader.get_node()

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

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

代码语言:javascript复制
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对象的字典。这个函数打算在构造函数中使用。

代码语言:javascript复制
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

自卸车

代码语言:javascript复制
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库。

代码语言:javascript复制
Dumper.emit(event)

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

代码语言:javascript复制
Dumper.open()
Dumper.serialize(node)
Dumper.close()

Dumper.open()发出StreamStartEvent

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

Dumper.close()发出StreamEndEvent

代码语言:javascript复制
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

代码语言:javascript复制
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

代码语言:javascript复制
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,如需转载请自行联系原作者

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/179766.html原文链接:https://javaforall.cn

0 人点赞