zoukankan      html  css  js  c++  java
  • PyYaml简单学习

    YAML是一种轻型的配置文件的语言,远比JSON格式方便,方便人类读写,它通过缩进来表示结构,很具有Python风格。
    安装:pip insall pyyaml

    YAML语法

    • 文档

    YAML数据流是0个或者多个文档,文档之间用---分割,文档可选用...结束,单个文档可用也可不用---开头。

    隐式文档如下:

    """
    - Multimedia
    - Internet
    - Education
    """
    
    '
    - Multimedia
    - Internet
    - Education
    '
    

    显式文档如下:

    """
    ---
    - Multimedia
    - Internet
    - Education
    ...
    """
    
    '
    ---
    - Multimedia
    - Internet
    - Education
    ...
    '
    
    • 序列

    序列用-空格来表示

    yaml.load("""
    - The Dagger
    - The daager
    - The Daaage
    """)
    
    ['The Dagger', 'The daager', 'The Daaage']
    

    序列可以嵌套:

    yaml.load("""
    -
        - HTML
        - LaTex
        - XML
        - VRML
        - YAML
    -
        - BSD
        - GNU HURD
        - LINUX
    """)
    
    [['HTML', 'LaTex', 'XML', 'VRML', 'YAML'], ['BSD', 'GNU HURD', 'LINUX']]
    

    也可不用另起一行来新建嵌套的序列:

    yaml.load("""
    - 1.1
    - - 2.1
      - 2.2
    - - - 3.1
        - 3.2
        - 3.3
    
    """)
    
    [1.1, [2.1, 2.2], [[3.1, 3.2, 3.3]]]
    

    序列也可以嵌套到映射中:

    yaml.load("""
    left hand:
            - Ring of Tesla
            - Ring of King
    right hand:
            - Ring of Asia
            - Ring of Cold
    """)
    
    {'left hand': ['Ring of Tesla', 'Ring of King'],
     'right hand': ['Ring of Asia', 'Ring of Cold']}
    
    • 映射

    键值对用:空格来表示:

    yaml.load("""
    base armor: 0
    base damaage: [4,4]
    plus to: 16
    multi:
        - test test
        - tets
    """)
    
    {'base armor': 0,
     'base damaage': [4, 4],
     'plus to': 16,
     'multi': ['test test', 'tets']}
    

    复杂的键可以用?空格,比如字典的键如果是tuple类型,而序列是List,众所周知,Python中字典的键只能是不可变的对象,所以需要将List 转换为tuple.

    yaml.load("""
    ? !!python/tuple [0,0] 
    : The hero
    """)
    
    {(0, 0): 'The hero'}
    

    映射也可以嵌套:

    yaml.load("""
    hero: 
        hp: 34
        sp: 9
    orc:
        hp: 12
        sp: 34
    """)
    
    {'hero': {'hp': 34, 'sp': 9}, 'orc': {'hp': 12, 'sp': 34}}
    

    映射也可以嵌套在序列中

    yaml.load("""
    - name: PyYAML
      status: 4
      langauage: python
    - name: PYSYCK
      status: 5
      license: BSD
    """)
    
    [{'name': 'PyYAML', 'status': 4, 'langauage': 'python'},
     {'name': 'PYSYCK', 'status': 5, 'license': 'BSD'}]
    
    • 标量

    有5种标量:纯文本,单引号,双一号,字面量,折叠式

    yaml.load("""
    plain: Scroll of Remove Curse
    single-quoted: 'Easy know'
    double-quoted: "?"
    literal:
         __              /.-.
        /  )_____________\  Y
       /_ /=== == === === = _\_
      ( /)=== == === === == Y   
       `-------------------(  o  )
                            \___/
    folded: >
     It removed all ordinary curses from all equipped items. # 注意开头的空格
     Heavy or permanent curses are unaffected  
    
    """)
    
    {'plain': 'Scroll of Remove Curse',
     'single-quoted': 'Easy know',
     'double-quoted': '?',
     'literal': '__              /.-.    /  )_____________\  Y /_ /=== == === === =\ _\_ ( /)=== == === === == Y      `-------------------(  o  ) \___/',
     'folded': 'It removed all ordinary curses from all equipped items. # 注意开头的空格 Heavy or permanent curses are unaffected  
    '}
    

    加载YAML

    import yaml
    

    直接用yaml.load来加载一个不可信任的文件是非常不安全的,yaml.loadpickle.load一样强大,都可以调用任何Python函数。可以考虑用yaml.safe_load

    yaml.load将一个YAML文档转化为一个Python对象。

    需要注意的是 '-' 与字符串之间需要有空格,才表示一个列表。

    a=yaml.load("""
     - Hesper
     - Pali
     - Apat
     - Epip
    """)
    
    a
    
    ['Hesper', 'Pali', 'Apat', 'Epip']
    
    type(a)
    
    list
    
    yaml.load("""
     测试: 中文 
     age: 30
    """) 
    
    {'测试': '中文', 'age': 30}
    

    需要重要的是 :与字符串之间也有空格

    • 如果一个字符串或者文件包含多个文档,可以用yaml.load_all函数。
    documents="""
    ---
    name: first one
    description: dkfsjk
    ---
    name: johnyang
    age: 29
    
    ---
    - C
    - C++
    - C#
    - B #
    """
    

    注意多个文档之间用---分割。

    yaml.load_all(documents)
    
    <generator object load_all at 0x0000029B36EC2390>
    
    for data in yaml.load_all(documents):
        print(data)
    
    {'name': 'first one', 'description': 'dkfsjk'}
    {'name': 'johnyang', 'age': 29}
    ['C', 'C++', 'C#', 'B']
    

    空格 '#'是表示注释

    • PyYAML允许构建任意类型的Python对象
    yaml.load("""
    none: [~,null]
    bool: [ture,false,on,off]
    int: 42
    float: 3.14159
    list: [LIST,RES]
    dict: {hhp: 13,sps: dkf}
    multiDict:
            dksk: fjsdk
            jfksd: eiw
    """)
    
    {'none': [None, None],
     'bool': ['ture', False, True, False],
     'int': 42,
     'float': 3.14159,
     'list': ['LIST', 'RES'],
     'dict': {'hhp': 13, 'sps': 'dkf'},
     'multiDict': {'dksk': 'fjsdk', 'jfksd': 'eiw'}}
    
    • 甚至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: jksdfk
    hp: 1200
    sp: 0
    
    """)
    
    Hero(name='jksdfk',hp=1200,sp=0)
    

    注意 !!python/object:__main__.Hero中的:后面没有空格!

    导出YAML

    yaml.dump接受Python对象,导出为一个YAML文档。

    print(yaml.dump({'name':'johnyang','age':29,'hobby':['coding','reading','thinking']}))
    
    age: 29
    hobby: [coding, reading, thinking]
    name: johnyang
    

    yaml.dump接受第二个可选的参数,必须是打开的文本/二进制文件,这种情况下,yaml.dump将会把产生的yaml文档写入该文本,否则yaml.dump返回产生的文档。

    stream=open('testYaml.yaml','w')
    
    yaml.dump(data,stream)
    
    print(yaml.dump(data))
    
    {age: 29, name: johnyang}
    

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

    print(yaml.dump(Hero('Gauss',hp=-3,sp=3)))
    
    !!python/object:__main__.Hero {hp: -3, name: Gauss, sp: 3}
    

    • yaml.dump支持管控输出格式的可选参数
    print(yaml.dump(list(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(list(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(list(range(5)),canonical=True)) #canonical 意思是典型的;规范化
    
    ---
    !!seq [
      !!int "0",
      !!int "1",
      !!int "2",
      !!int "3",
      !!int "4",
    ]
    

    print(yaml.dump(list(range(5)),default_flow_style=False))
    
    - 0
    - 1
    - 2
    - 3
    - 4
    

    print(yaml.dump(list(range(5)),default_flow_style=True))
    
    [0, 1, 2, 3, 4]
    

    print(yaml.dump(list(range(5)),default_flow_style=True,default_style='""'))
    
    [!!int "0", !!int "1", !!int "2", !!int "3", !!int "4"]
    

    
    
    ##### 愿你一寸一寸地攻城略地,一点一点地焕然一新 #####
  • 相关阅读:
    IE10、IE11下SCRIPT5009: “__doPostBack”未定义
    CSS Hack大全-可区分出IE6-IE10、FireFox、Chrome、Opera
    HTML head 头标签
    html5匹配不同分辨率样式
    html5关键帧动画,一个小例子快速理解关键帧动画
    导入Excel到数据库
    JavaScript树(一) 简介
    深入解析浏览器的幕后工作原理(五) 呈现树
    深入解析浏览器的幕后工作原理(四) DOM树
    深入解析浏览器的幕后工作原理(三) 呈现树和 DOM 树的关系
  • 原文地址:https://www.cnblogs.com/johnyang/p/14158543.html
Copyright © 2011-2022 走看看