yaml在python中的應用簡單整理

#簡單介紹==============================================================node

YAML使用寄主語言的數據類型,這在多種語言中流傳的時候可能會引發兼容性的問題。python

YAML語法規則:app

  http://www.ibm.com/developerworks/cn/xml/x-cn-yamlintro/ide

  http://www.yaml.org/函數

事例:this

name: Tom Smith  
age: 37  
spouse:  
    name: Jane Smith  
    age: 25  
children:  
 - name: Jimmy Smith  
   age: 15  
 - name1: Jenny Smith  
   age1: 12 

使用python的yaml庫PyYAML。http://pyyaml.org/編碼

#在python中的應用======================================================== spa

安裝到python lib下後就能夠正常使用了。scala

主要介紹yaml在python中如何讀寫。code

一、讀取單個yaml文件

yaml.load()方法

使用舉例:

 1 #加載yaml
 2 import yaml
 3 
 4 #讀取文件
 5 f = open('test.yaml')
 6 
 7 #導入
 8 x = yaml.load(f)
 9 
10 print x

會獲得結果:

 {'age': 37, 'spouse': {'age': 25, 'name': 'Jane Smith'}, 'name': 'Tom Smith', 'children': [{'age': 15, 'name': 'Jimmy Smith'}, {'age1': 12, 'name1': 'Jenny Smith'}]}

在讀取yaml文件時,對文件格式的要求極其的嚴格。有時候沒有報錯,卻讀不出任何內容。

文件的格式錯誤也是常有的事,注意:

yaml.load accepts a byte string, a Unicode string, an open binary file object, or an open text file object. A byte string or a file must be encoded with utf-8utf-16-be or utf-16-le encoding. yaml.load detects the encoding by checking the BOM (byte order mark) sequence at the beginning of the string/file. If no BOM is present, theutf-8 encoding is assumed.

yaml.load可接收一個byte字符串,unicode字符串,打開的二進制文件或文本文件對象。字節字符串和文件必須是utf-8,utf-16-be或utf-16-le編碼的.yaml.load經過檢查字符串/文件開始的BOM(字節序標記)來確認編碼。若是沒有BOM,就默認爲utf-8。

二、讀取多個yaml

yaml.load_all()

若是string或文件包含幾塊yaml文檔,你可使用yaml.load_all來解析所有的文檔。

1 yaml.load(stream, Loader=<class 'yaml.loader.Loader'>)
2     Parse the first YAML document in a stream #只解析第一個
3     and produce the corresponding Python object.
4 
5 yaml.load_all(stream, Loader=<class 'yaml.loader.Loader'>)
6     Parse all YAML documents in a stream
7     and produce corresponding Python objects.

注意,yaml.load_all 會生成一個迭代器,你要作的就是for 讀出來

 1 documents = """
 2 name: The Set of Gauntlets 'Pauraegen'
 3 description: >
 4   A set of handgear with sparks that crackle
 5   across its knuckleguards.
 6  ---
 7 name: The Set of Gauntlets 'Paurnen'
 8 description: >
 9    A set of gauntlets that gives off a foul,
10    acrid odour yet remains untarnished.
11  ---
12 name: The Set of Gauntlets 'Paurnimmen'
13 description: >
14    A set of handgear, freezing with unnatural cold.
15 """
16 
17 
18 for data in yaml.load_all(documents):
19 print data
20 
21 #{'description': 'A set of handgear with sparks that crackle across its #knuckleguards.\n',
22 #'name': "The Set of Gauntlets 'Pauraegen'"}
23 #{'description': 'A set of gauntlets that gives off a foul, acrid odour #yet remains untarnished.\n',
24 #'name': "The Set of Gauntlets 'Paurnen'"}
25 #{'description': 'A set of handgear, freezing with unnatural cold.\n',
26 #'name': "The Set of Gauntlets 'Paurnimmen'"}

safe_load描述

PyYAML allows you to construct a Python object of any type.

Even instances of Python classes can be constructed using the !!python/object tag.

 PyYaml容許你構建任何類型的python對象,甚至是python類實例,只須要藉助一下yaml標籤!!python/object。

這個之後再說,很是有用的東西。

 Note that the ability to construct an arbitrary Python object may be dangerous if you receive a YAML document from an untrusted source such as Internet. The function yaml.safe_load limits this ability to simple Python objects like integers or lists.

 須要注意的是隨意在yaml裏構建python對象是有必定危險的,尤爲是接收到一個未知的yaml文檔。yaml.safe_load能夠限制這個能力,就使用些簡單的對象吧。

三、寫yaml文件

yaml.dump 將一個python對象生成爲yaml文檔,與yaml.load搭配使用。

1 dump(data, stream=None, Dumper=<class 'yaml.dumper.Dumper'>, **kwds)
2 
3     Serialize a Python object into a YAML stream.
4     If stream is None, return the produced string instead.
5     #很好,若是缺省數據流爲空的話,就會給你返回個字符串做爲yaml文檔

應用事例:

 1 aproject = {'name': 'Silenthand Olleander', 
 2                    'race': 'Human',
 3                     'traits': ['ONE_HAND', 'ONE_EYE']
 4                    }
 5 
 6 
 7 print yaml.dump(aproject)
 8 
 9 #返回
10 #name: Silenthand Olleander
11 #race: Human
12 #traits: [ONE_HAND, ONE_EYE]

yaml.dump accepts the second optional argument, which must be an open text or binary file. In this case,yaml.dump will write the produced YAML document into the file. Otherwise, yaml.dump returns the produced document. 

  解釋上面那句話的:yaml.dump接收的第二個參數必定要是一個打開的文本文件或二進制文件,yaml.dump會把生成的yaml文檔寫到文件裏。不然,yaml.dump會返回生成的文檔。

四、寫多個yaml內容,yaml.dump_all函數

If you need to dump several YAML documents to a single stream, use the function yaml.dump_all.yaml.dump_all accepts a list or a generator producing

Python objects to be serialized into a YAML document. The second optional argument is an open file.

 若是你須要把幾段yaml文檔同時寫進一個數據流中,請使用yaml.dump_all函數。yaml.dump_all能夠接收一個列表或者生成python對象的可序列化生成器(好彆扭啊),第二個參數是打開的文件。這徹底是對應yaml.load_all的。

yaml.dump supports a number of keyword arguments that specify formatting details for the emitter. For instance, you may set the preferred intendation and width, use the canonical YAML format or force preferred style for scalars and collections.

 yaml.dump支持不少種肯定格式化發射器的關鍵字參數(請先無視這句- -#)。好比你能夠設置縮進和寬度(指的yaml文檔),使用標準yaml格式或者強制優先樣式對於標量和收集(請繼續無視- -#)。

1 dump_all(documents, stream=None, Dumper=<class 'yaml.dumper.Dumper'>, default_style=None, default_flow_style=None, canonical=None, indent=None, width=None, allow_unicode=None, line_break=None, encoding='utf-8', explicit_start=None, explicit_end=None, version=None, tags=None)
2 
3 
4 #不過對應具體的函數參數能夠看出所敘述的幾個參數
5 #cannonical
6 #indent
7 #width
8 #等等

例:

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

參數仍須要研究。

#下面沒看懂,先記下來,慢慢研究===================================================================

 Constructors, representers, resolvers

 構造器,描繪器(?),解析器

 You may define your own application-specific tags. The easiest way to do it is to define a subclass ofyaml.YAMLObject

 你能夠自定義一個程序專屬標籤(tag),定義一個yaml.YAMLObject的子類的最簡單方法能夠這麼幹:

 1 class Monster(yaml.YAMLObject):
 2     yaml_tag = u'!Monster'
 3     def __init__(self, name, hp, ac, attacks):
 4         self.name = name
 5         self.hp = hp
 6         self.ac = ac
 7         self.attacks = attacks
 8     def __repr__(self):
 9         return "%s(name=%r, hp=%r, ac=%r, attacks=%r)" % (
10             self.__class__.__name__, self.name, self.hp, self.ac,self.attacks)

 

The above definition is enough to automatically load and dump Monster objects:

     上面這個定義的Monster類已經足夠用來load和dump了:

 1 >>> yaml.load("""
 2 ... --- !Monster
 3 ... name: Cave spider
 4 ... hp: [2,6]    # 2d6
 5 ... ac: 16
 6 ... attacks: [BITE, HURT]
 7 ... """)
 8 
 9 Monster(name='Cave spider', hp=[2, 6], ac=16, attacks=['BITE', 'HURT'])
10 
11 >>> print yaml.dump(Monster(
12 ...     name='Cave lizard', hp=[3,6], ac=16, attacks=['BITE','HURT']))
13 
14 !Monster
15 ac: 16
16 attacks: [BITE, HURT]
17 hp: [3, 6]
18 name: Cave lizard

yaml.YAMLObject uses metaclass magic to register a constructor, which transforms a YAML node to a class instance, and a representer, which serializes a class instance to a YAML node.

 yaml.YAMLObject 使用魔法元類註冊一個把yaml編碼轉成類實例的構造器,還有一個把類實例序列化成yaml編碼的描述器。

 If you don't want to use metaclasses, you may register your constructors and representers using the functionsyaml.add_constructor and yaml.add_representer. For instance, you may want to add a constructor and a representer for the following Dice class:

 若是不想使用元類,也可使用函數yaml.add_constructor和yaml.add_representer來註冊構造器和描述器。例如,你能夠把一個構造器和描述器加到下面這個Dice類裏:

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

The default representation for Dice objects is not nice:

 這個Dice對象默認的yaml描述可不怎麼好看:

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

Suppose you want a Dice object to represented as AdB in YAML:

 好,如今假設你想把Dice對象描述成在yaml裏爲"AdB"的形式(A,B爲變量)。

 First we define a representer that convert a dice object to scalar node with the tag !dice and register it.

 首先咱們定義一個能夠把Dice對象轉換成帶有'!dice'標籤節點的描述器,而後註冊。

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

 

Now you may dump an instance of the Dice object:

 如今你就能夠dump一個Dice實例了:

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

Let us add the code to construct a Dice object:

 讓咱們把節點加到Dice對象的構造器中。

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

 

Then you may load a Dice object as well:

 而後就可使用了

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

從這裏能夠看出了,constructor和representer是相對的,一個爲load,一個爲dump。

博客原文:http://angeloce.iteye.com/blog/385976

相關文章
相關標籤/搜索