当前位置: 首页 > news >正文

python-第三方库-[yarl、yaml]

python-第三方库-[yarl、yaml]

  • 一: yarl
    • 1> yarl 介绍
    • 2> yarl.URL 介绍
      • 1. yarl.URL 的语法格式
      • 2. yarl.URL demo
      • 3. yarl.URL.build()
      • 4. yarl.URL().with_*()
      • 5. yarl.URL().update_query()
      • 6> url / &%组合
  • 二:yaml
    • 1> yaml 介绍
    • 2> yaml 基本规则
      • 1. 数据结构介绍
        • 普通样式、单/双引号样式
        • 字面样式(literal )
        • 折叠样式(folded)
        • Mappings(映射)
      • 2. 语法锚点和引用
        • 定义锚点&引用锚点
        • 锚定映射&序列节点
        • 合并映射-merge key
      • 3. yaml tag
        • tag 介绍
        • 自定义tag
    • 3> yaml demo
      • 1. yaml.load
      • 2. yaml.load Unicode&yaml.Loader
      • 3. yaml.dump&Unicode
      • 4. yaml.load_all
      • 5. yaml 与编码对象class
      • 6. yaml 多个编码对象class
      • 7. yaml.safe_load
    • 4> yaml 三大组件
        • 1. 构造器、表示器、解析器 介绍
        • 2. 构造&转存
        • 3. 序列化构造器
        • 4. 自定义构造器
    • 5> yaml引用环境变量
    • 6> libyaml
    • 7> FAQ
      • 1. yaml.safe_load&load区别

一: yarl

1> yarl 介绍

URL介绍:统一资源定位符,它是用来表示互联网上的某个资源地址,互联网上的每个文件都有一个唯一的 URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它;
yarl :yarl 库是一个强大的工具,用于处理 URL(统一资源定位符);
yarl作用:提供了简单且灵活的 API,使得 URL 的解析、构建和操作变得简单;

2> yarl.URL 介绍

from yarl import URL

1. yarl.URL 的语法格式

在这里插入图片描述

URL 的语法格式:
protocol://hostname[:port]/path[?query][#fragment]
part含义注释
protocol指网络传输协议以下是经常用到的几个协议;
http,通过 HTTP 协议访问该资源,格式 http://;
https,通过安全的 HTTPS 协议访问该资源, 格式 https://;
file,资源是本地计算机上的文件,格式 file://
ftp,通过 FTP访问资源,格式 FTP://
hostname主机名指存放资源的服务器的域名、主机名或 IP 地址。有时,在主机名前也可以包含连接到服务器所需的用户名和密码(格式:username:password@hostname)
port端口号port 是一个可选的整数,它的取值范围 是 0-65535。如果 port 被省略时就使用默认端口,各种传输协议都有默认的端口号,如 http 的默认端口为 80,https 的端口是 443;
path路由地址由零个或多个/符号隔开的字符串,一般用来表示主机上的一个目录或文件地址。路由地址决定了服务端如何处理这个请求;
query查询从?开始到#为止,它们之间的部分就是参数,又称搜索部分或者查询字符串。这个部分允许有多个参数,参数与参数之间用&作为分隔符;下面demo 为:spm=1011.2124.3001.5298
fragment信息片断它用于指定网络资源中的片断,例如一个网页中有多个名词解释,那么可使用 fragment 直接对它们定位

2. yarl.URL demo

from yarl import URLurl_string = "https://mp.csdn.net/mp_blog/manage/article?spm=1011.2124.3001.5298"
url = URL(url_string)print(url)
print(url.scheme)
print(url.host)
print(url.port)
print(url.authority)print(url.path)
print(url.query)
print(url.query_string)print(url.user)
print(url.password)
=======================
https://mp.csdn.net/mp_blog/manage/article?spm=1011.2124.3001.5298
https
mp.csdn.net
443
mp.csdn.net:443
/mp_blog/manage/article
<MultiDictProxy('spm': '1011.2124.3001.5298')>
spm=1011.2124.3001.5298None
None

3. yarl.URL.build()

from yarl import URLurl = URL.build(scheme='https',host='mp.csdn.net',port=443,path='/mp_blog/manage/article',query={'spm': '1011.2124.3001.5298'})
print(url)
===============
https://mp.csdn.net:443/mp_blog/manage/article?spm=1011.2124.3001.5298

4. yarl.URL().with_*()

with_scheme、with_user 、with_password 、with_host 、with_port、with_path、with_query、with_fragment、with_name

with_*() 单步骤构建

from yarl import URLurl = URL.build(scheme='https',host='mp.csdn.net',port=443,path='/mp_blog/manage/article',)
query = {'spm': '1011.2124.3001.5298'}print(url.with_query(query))

with_().with_()多步骤构建url

from yarl import URLurl = URL.build(scheme='https',host='mp.csdn.net',port=443,)
print(url)
query = {'spm': '1011.2124.3001.5298'}
print(url.with_path('/mp_blog/manage/article').with_query(query))
============================
https://mp.csdn.net:443
https://mp.csdn.net:443/mp_blog/manage/article?spm=1011.2124.3001.5298

5. yarl.URL().update_query()

url.with_query(query):清除之前的query 信息;

from yarl import URLurl = URL.build(scheme='https',host='mp.csdn.net',port=443,path='/mp_blog/manage/article',query = {'spm': '1011.2124.3001.5298'})query = {'xxx': '127.0.0.1', '***': '128.0.0.1'}
print(url.with_query(query))
===================
https://mp.csdn.net:443/mp_blog/manage/article?xxx=127.0.0.1&***=128.0.0.1

url.update_query(query):对之前存在信息进行更新;

from yarl import URLurl = URL.build(scheme='https',host='mp.csdn.net',port=443,path='/mp_blog/manage/article',query = {'spm': '1011.2124.3001.5298'})query = {'xxx': '127.0.0.1', '***': '128.0.0.1'}
print(url.update_query(query))
=============================
https://mp.csdn.net:443/mp_blog/manage/article?spm=1011.2124.3001.5298&xxx=127.0.0.1&***=128.0.0.1

6> url / &%组合

from yarl import URL
url = (
URL('https://mp.csdn.net')/
'mp_blog/manage/article'%
{'spm': '1011.2124.3001.5298'}
)print(url)
=====================
https://mp.csdn.net/mp_blog/manage/article?spm=1011.2124.3001.5298

二:yaml

1> yaml 介绍

Yaml :Yaml 是一种人类可读的数据序列化语言,通常用于存储项目中的配置文件;例如 docker 和 k8s 都使用 Yaml 文件定义部署信息;类似于 json 数据,但 Yaml 的格式更加丰富,可以存储更复杂的数据结构

2> yaml 基本规则

规则说明
层级关系yaml 的层级关系通过缩进表示,缩进空格数没有规定,但同层级的缩进必须一致。建议全局使用相同的缩进空格数;
存储数据yaml 使用键值对的方式存储数据。 - 在键值对的值前面添加 - 符号表示这个键的值是一个列表

1. 数据结构介绍

YAML中,有3种基本的数据结构:Scalars(标量)、Sequences(序列)和Mappings(映射)

数据结构说明举例
Scalars标量是单个的、不可再分的值。标量可以是字符串、数字、布尔值、null、日期等1. 普通样式、单/双引号样式
2. 字面样式(literal )
3. 折叠样式(folded)
序列(Sequences)序列是一组按次序排列的值,每一个元素都可以是任意数据类型连字符-开头的行构成一个序列;
- A
- B
- C
==>
key: [A, B, C]
Mappings(映射)映射是一种键值对的集合,其中每个键都必须唯一每个键值对用冒号+一个空格分隔(key: value)
普通样式、单/双引号样式
import yamldocument = """
爱好1: 喝酒唱歌
爱好2: '喝酒唱歌'
"""res = yaml.load(document, Loader=yaml.Loader)
print(res)
============
{'爱好1': '喝酒 唱歌', '爱好2': '喝酒\n唱歌'}
字面样式(literal )
import yamldocument = """
爱好1: |喝酒唱歌
爱好2: '喝酒唱歌'
"""res = yaml.load(document, Loader=yaml.Loader)
print(res)
=====================
{'爱好1': '喝酒\n唱歌\n', '爱好2': '喝酒\n唱歌'}
折叠样式(folded)
import yamldocument = """
爱好1: >喝酒唱歌
爱好2: '喝酒唱歌'
"""res = yaml.load(document, Loader=yaml.Loader)
print(res)
==============
{'爱好1': '喝酒 唱歌\n', '爱好2': '喝酒\n唱歌'}
Mappings(映射)
import yamldocument = """
爱好1: 喝酒
爱好2: 唱歌
"""
res = yaml.load(document, Loader=yaml.Loader)
print(res)
============
{'爱好1': '喝酒', '爱好2': '唱歌'}

2. 语法锚点和引用

编程中我们通常用变量引用来解决这种问题,YAML也提供了一种类似的机制实现变量引用,它就是锚点引用(Anchors and Aliases);例如:同的数据被重复使用, 配置信息,

定义锚点&引用锚点
import yamldocument = """
key: &anchor pig
key2: *anchor
key3: *anchor
"""
'''
1. 使用 & 符号可以定义一个锚点
2. * 符号+锚点名 可以引用先前定义的锚点
'''
res = yaml.load(document, Loader=yaml.Loader)
print(res)
=================
{'key': 'pig', 'key2': 'pig', 'key3': 'pig'}
锚定映射&序列节点
import yamldocument = """
# 定义一个共享的内容
common_data: &anchor_idname: Common Namevalue: Common Value# 使用锚定引用共享内容
nodes:- *anchor_id- *anchor_id"""'''
1. common_data: &anchor_id: 是一个锚定的名字,它指向一个映射(即键值对的集合)
2. *anchor_id 是一个别名,用来引用先前定义的那个映射
3. nodes 是一个list, 引用anchor_id
'''
res = yaml.load(document, Loader=yaml.Loader)
print(res)=================
{'common_data': {'name': 'Common Name', 'value': 'Common Value'}, 'nodes': [{'name': 'Common Name', 'value': 'Common Value'}, {'name': 'Common Name', 'value': 'Common Value'}]}
合并映射-merge key

YAML提供了一种<<语法用于合并映射(Mappings)。它允许你将一个映射的键值对合并到另一个映射中,从而实现映射之间的继承和合并。这种语法也被称为"merge key";
提高代码的可维护性和可读性。这对于定义共享的配置或基本设置,并在派生配置中进行定制化非常有用

import yamldocument = """
base: &tmp_basename: Johnage: 30
extension:<<: *tmp_baseage: 31city: New York 
"""# 在base基础上update extension 信息res = yaml.load(document, Loader=yaml.Loader)
print(res)
===================
{'base': {'name': 'John', 'age': 30}, 'extension': {'name': 'John', 'age': 31, 'city': 'New York'}}

3. yaml tag

AML中,标签(Tags)用于对数据进行类型标识或自定义标识。它们提供了一种扩展YAML数据模型的方式;

tag 介绍
tag说明demo
!!str标识字符串类型name: !!str John
!!int标识整数类型count: !!int 10
!!float标识浮点数类型pi: !!float 3.1415926
!!bool标识布尔类型is_valid: !!bool true
!!null标识nulldata: !!null
隐式tag隐式声明boolean: !!bool “true”
integer: !!int “3”
显式tag显式声明boolean: true
integer: 3
自定义tag
yaml tagpython type
!!nullNone
!!boolbool
!!intint or long (int in Python 3)
!!floatfloat
!!binarystr (bytes in Python 3)
!!timestampdatetime.datetime
!!omap, !!pairslist of pairs
!!setset
!!strstr or unicode (str in Python 3)
!!seqlist
!!mapdict
Python-specifictags
!!python/noneNone
!!python/boolbool
!!python/bytes(bytes in Python 3)
!!python/strstr (str in Python 3)
!!python/unicodeunicode (str in Python 3)
!!python/intint
!!python/longlong (int in Python 3)
!!python/floatfloat
!!python/complexcomplex
!!python/listlist
!!python/tupletuple
!!python/dictdict

3> yaml demo

配置文件用 .yaml 或者 .py 形式如下

1. yaml.load

import yamldocument = """
conv_001:op_list:- Conv2d- Conv2dcreat_params:selector: - F- Flayer1:in_channels: 1out_channels: 1kernel_size: 3stride: 2padding: 1groups: 1layer2:in_channels: 1out_channels: 2kernel_size: 3stride: 4padding: 1groups: 1quant_params:data_num: 1inputShape: - [1, 1, 224, 8]
"""res = yaml.load(document, Loader=yaml.Loader)
print(res)
print(type(res))
=======================
{'conv_001': {'op_list': ['Conv2d', 'Conv2d'], 'creat_params': {'selector': ['F', 'F'], 'layer1': {'in_channels': 1, 'out_channels': 1, 'kernel_size': 3, 'stride': 2, 'padding': 1, 'groups': 1}, 'layer2': {'in_channels': 1, 'out_channels': 2, 'kernel_size': 3, 'stride': 4, 'padding': 1, 'groups': 1}}, 'quant_params': {'data_num': 1, 'inputShape': [[1, 1, 224, 8]]}}}
<class 'dict'>

2. yaml.load Unicode&yaml.Loader

使用 Loader=yaml.Loader 实现Unicode

import yamldocument = """
姓名: 小明,
爱好:- 喝酒- 唱歌- 赌牌- 打游戏
"""res = yaml.load(document, Loader=yaml.Loader)
print(res)
print(type(res))

3. yaml.dump&Unicode

import yaml
import osdocument = """
姓名: 小明,
爱好:- 喝酒- 唱歌- 赌牌- 打游戏
"""res = yaml.load(document, Loader=yaml.Loader)
document_name = f'document.yaml'
with open(document_name, 'w') as file:yaml.dump(res, file, default_flow_style=False, encoding='utf-8', allow_unicode=True)
'''
数据中包含中文等 Unicode 字符,yaml.dump() 会将它们编码成不可读的表示方式。为了解决这个问题,
可以添加三个关键字参数,使中文等 Unicode 字符以可读形式保存,default_flow_style, encoding, allow_unicode
'''
print(os.path.exists(document_name))
with open(document_name, 'r') as f:res_load = yaml.load(f, Loader=yaml.Loader)
print(res_load)
===================
True
{'姓名': '小明,', '爱好': ['喝酒', '唱歌', '赌牌', '打游戏']}

4. yaml.load_all

aml文档中,使用 — 符号可以分段。对于带有分段的Yaml文档,使用 yaml.load() 函数会报错,需要使用 yaml.load_all() 函数;

import yamldocument = """
姓名: 小明,
爱好:- 喝酒- 唱歌- 赌牌- 打游戏
---
姓名: 小红,
爱好:- 写字- 看书
"""res = yaml.load_all(document, Loader=yaml.Loader)
print(type(res))
for i in res:print(i)
====================
<class 'generator'>
{'姓名': '小明,', '爱好': ['喝酒', '唱歌', '赌牌', '打游戏']}
{'姓名': '小红,', '爱好': ['写字', '看书']}

5. yaml 与编码对象class

import yamlclass Anmails:def __init__(self, name, likes):self.name = nameself.likes = likesdef __repr__(self):return f'{self.__class__.__name__}(name={self.name}, like={self.likes})'def like(self):print(f'我是{self.name},我喜欢{str(self.likes)}! ')to_do = Anmails('猪', ['喝酒', '唱歌', '赌牌', '打游戏'])
document = yaml.dump(to_do)
like_A = yaml.load(document, Loader=yaml.Loader)
print(yaml.dump(to_do))
print(like_A)
print(type(like_A))
like_A.like()
=======================
!!python/object:__main__.Anmails
likes:
- "\u559D\u9152"
- "\u5531\u6B4C"
- "\u8D4C\u724C"
- "\u6253\u6E38\u620F"
name: "\u732A"Anmails(name=猪, like=['喝酒', '唱歌', '赌牌', '打游戏'])
<class '__main__.Anmails'>
我是猪,我喜欢['喝酒', '唱歌', '赌牌', '打游戏']!

6. yaml 多个编码对象class


import yamlclass Anmails:def __init__(self, name, likes):self.name = nameself.likes = likesdef __repr__(self):return f'{self.__class__.__name__}(name={self.name}, like={self.likes})'def like(self):print(f'我是{self.name},我喜欢{str(self.likes)}! ')to_do1 = Anmails('猪', ['喝酒', '唱歌', '赌牌', '打游戏'])
to_do2 = Anmails('de-lovely', ['写字', '看书'])
document_name = r'document.yaml'
with open(document_name, 'w') as f:yaml.dump_all([to_do1, to_do2], f, default_flow_style=False, encoding='utf-8', allow_unicode=True)==============
document.yaml:
!!python/object:__main__.Anmails
likes:
- 喝酒
- 唱歌
- 赌牌
- 打游戏
name: 猪
--- !!python/object:__main__.Anmails
likes:
- 写字
- 看书
name: de-lovely

7. yaml.safe_load

import yamldocument_name = 'document.yaml'
with open(document_name, 'r') as f:# case_params = yaml.load(f, Loader=yaml.Loader)case_params = yaml.safe_load(f)
print(case_params)#修改参数
case_params['conv_001']['creat_params']['layer1']['groups'] = 2
case_params['conv_001']['op_list'][0] = 'Conv3d'
#保存参数
with open('document_currect.yaml', 'w') as file:yaml.dump(case_params, file)

在这里插入图片描述

4> yaml 三大组件

1. 构造器、表示器、解析器 介绍
组件功能描述
Constructors(构造器)用于将 YAML 数据解析为 Python 对象的组件,将 YAML 数据的不同类型转换为相应的 Python 对象。PyYAML 提供了一些内置的构造器,用于处理常见的数据类型,如字符串、整数、浮点数、布尔值等。同时,你也可以自定义构造器,以便将 YAML 数据解析为自定义的 Python 类型。通过注册构造器,你可以扩展 PyYAML 的解析功能,使其能够处理更多的数据类型;
Representers(表示器)与构造器相反,Representers 是用于将 Python 对象表示为 YAML 数据的组件,它们负责将 Python 对象转换为 YAML 中的相应表示形式PyYAML 提供了一些内置的表示器,用于处理常见的 Python 对象类型,如字符串、整数、浮点数、布尔值等。同时,你也可以自定义表示器,以便将自定义的 Python 类型表示为 YAML 数据。通过注册表示器,你可以定制 PyYAML 的转储功能,使其能够生成符合特定需求的 YAML 数据。
Resolvers(解析器)Resolvers 是用于解析 YAML 数据中的标签(Tags)的组件,它们负责识别标签并将其映射到相应的构造器和表示器PyYAML 提供了内置的标签解析器,用于处理常见的标准类型。同时,你也可以自定义解析器,以便识别和处理自定义的标签。通过注册解析器,你可以扩展 PyYAML 的标签识别功能,使其能够处理更多的数据类型和标签;
2. 构造&转存
import yamlclass Introduce(yaml.YAMLObject):yaml_tag = u'!Introduce'def __init__(self, name, likes):self.name = nameself.likes = likesdef __repr__(self):return f'{self.__class__.__name__}(name={self.name}, {self.likes})'document = """
!Introduce
name: xiaoming
likes:- games
"""
'''
1. !Introduce: 定义一个YAML标签用于解析和生成Monster类型数据
2. yaml.dump(res): 转储Monster对象为YAML格式数据
'''
res = yaml.load(document, Loader=yaml.Loader)
print(res)
print(type(res))
document_cp = yaml.dump(res)
print(document_cp)
=================
Introduce(name=xiaoming, ['games'])
<class '__main__.Introduce'>
!Introduce
likes:
- games
name: xiaoming
3. 序列化构造器
import yamlclass Dice(tuple):def __new__(cls, a, b):return tuple.__new__(cls, [a, b])def __repr__(self):return "Dice(%s,%s)" % selfdef dice_representer(dumper, data):return dumper.represent_scalar(u'!dice', u'%sd%s' % data)yaml.add_representer(Dice, dice_representer)
res = yaml.dump(Dice(3,6))
print(res)
============
!dice '3d6'无:# yaml.add_representer(Dice, dice_representer)
=========================
!!python/object/new:__main__.Dice
- !!python/tuple- 3- 6
4. 自定义构造器
import yamlclass Dice(tuple):def __new__(cls, a, b):return tuple.__new__(cls, [a, b])def __repr__(self):return "Dice(%s,%s)" % selfdef dice_representer(dumper, data):return dumper.represent_scalar(u'!dice', u'%sd%s' % data)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)res = yaml.load("initial hit points: !dice 8d4", yaml.Loader)
print(res)
==========
{'initial hit points': Dice(8,4)}

5> yaml引用环境变量

import yaml
import osdef render_env_constructor(loader, node):value = loader.construct_scalar(node)return os.path.expandvars(value)yaml.SafeLoader.add_constructor('!ENV', render_env_constructor)os.environ["a"]="111"
os.environ["b"]="222"
res = yaml.safe_load("test: !ENV a=${a}, b=$b")
#加载YAML时自动替换了标签!ENV标识标量的环境变量占位符
print(res)
=======
{'test': 'a=111, b=222'}

环境变量通常都是字符串形式。如果你使用了数字、布尔等其他类型,需要解析后手动转换。
os.path.expandvars是一个内置函数,用于展开字符串中的环境变量。它会在目标字符串中查找形式为 V A R 或 VAR或 VAR{VAR}的环境变量引用,并将其替换为响应的环境变量的值。如果找不到匹配的环境变量,那么引用保持不变

6> libyaml

libyaml介绍
libyaml库libyaml是一个独立的C库,用于处理 yaml数据的解析和生成。Pyyaml 可以使用 LibYAML 作为其解析和生成 yaml 数据的底层引擎;
特点LibYAML 具有高性能、低内存占用、加速 yaml数据处理
组件提供 CLoader 和 CDumper 两个组件用来集成 LibYAML;
CLoader: PyYAML 的解析器(Loader)的C扩展版本
CDumper: PyYAML的生成器(Dumper)的C扩展版本
CLoader和CDumper优势1. 通过与LibYAML的集成,提供了更高效的解析和生成功能;
2. 处理大型YAML数据时获得更好的性能和效率

7> FAQ

1. yaml.safe_load&load区别

load: Loader支持加载任意的Python对象,可能导致执行任意 Python 代码
safe_load:SafeLoader 限制了加载过程中执行的操作,只允许加载基本类型的对象,如字符串、整数、列表和字典等;当你处理来自不受信任的源或不确定性的 YAML 文件时,特别是从外部来源加载时,使用 SafeLoader 是一个良好的实践,可以提高安全性并防止可能的代码注入或其他潜在的安全问题


http://www.mrgr.cn/news/18791.html

相关文章:

  • 太狠了:华为的卫星通信能免费使用了
  • 环保专包二级资质续期时要避免的常见错误
  • ESP32无线WiFi芯片模组,设备物联网连接通信,产品智能化交互升级
  • 场外个股期权为什么那么火?收益翻倍不是梦!
  • 电商数据整合新篇章:京东商品详情API返回值应用实践
  • 全能型AI vs.专业型AI:未来趋势与市场潜力探讨
  • Kafka【六】Linux下安装Kafka集群
  • springboot、flowable 生成图片发布到Docker乱码问题
  • AOP和注解的配合使用(封装通用日志处理类)
  • 团建活动如何分组?
  • LearnOpenGL学习笔记
  • 探索电子翻书在展厅的应用,如何进一步优化信息展示与接收?
  • 高校为什么需要AIGC大数据实验室?
  • 青远生态为云南林业规划院定制开发的自然保护地规划智能编制系统顺利通过验收
  • ubunto中常见问题及WSL
  • 盘古信息IMS V6:先进稳定的企业数字化转型方案
  • 王立铭脑科学50讲后续5,自己从课程中提起自己所需的知识,安放到自己的知识体系中。
  • 使用dx工具将jar和class打包成dex
  • Web3社交新经济,与 SOEX 实现无缝交易的高级安全性
  • 软件测试基础知识整理(详细版)