「Python 基础」I/O 编程、正则表达式
文章目录
- 1. I/O 编程
- 文件读写
- StringIO 和 BytesIO
- 操作文件和目录
- 序列化
 
- 2. 正则表达式
- 进阶
- re 模块
 
 
1. I/O 编程
I/O指Input/Output;
Input Stream 从外面(磁盘、网络)流进内存;
Output Stream 从内存流到外面;
同步 I/O CPU 等待I/O完成,程序暂停后续执行;
异步 I/O CPU 不等待I/O完成,先做其他事,通过回调或轮询处理I/O后续;
文件读写
在磁盘上读写文件的功能都是有操作系统提供的,现代操作系统不允许普通程序直接操作磁盘;
文件流操作方法
| 方法 | 说明 | 
|---|---|
| open() | 以指定模式打开文件对象,参数为 文件名和模式标示符,可选参数encoding(编码)errors(编码错误处理方式) | 
| read() | 一次读取文件所有内容,返回 str对象 | 
| read(size) | 每次读取 size个字节的内容 | 
| readline() | 每次读取一行内容 | 
| readlines() | 一次读取所有内容,并返回以行分割的 list | 
| write() | 将要写入的内容写入内存缓存,当 close被调用时真正将内容写出 | 
| close() | 关闭文件,关闭前将内存缓存中的内容全部写出 | 
文件对象模式
| 字符 | 含义 | 
|---|---|
| r | 读取(默认) | 
| w | 写入,先 truncate 文件 | 
| x | 独占创建,如果文件已经存在则失败 | 
| a | 写入,如果文件已经存在则追加到文件末尾 | 
| b | 二进制模型 | 
| t | 文字模式(默认) | 
| + | 更新(读写) | 
读文件
with open('/Users/aurelius/test.txt', 'r') as f:print(f.read())
with语句可保证open的文件最终会被close,同样的功能可以通过try ... finally语句在finally中执行close实现;
写文件
with open('/User/aurelius/test.txt', 'w') as f:f.write('hello, world.')
StringIO 和 BytesIO
StringIO
在内存中读写str,和读写文件具有一致的接口;
from io import StringIO
# InputStream
f = StringIO()
f.write('hello')
# 读取写入的 str
f.getvalue()# OutputStream
f = StringIO('hello, 中国')
f.read()
BytesIO
在内存中读写bytes
from io import BytesIO
# InputStream
f = BytesIO()
f.write('中文'.encode('utf-8'))
print(f.getvalue())# OutputStream
f = BytesIO(b'\xe4\xb8\xad\xe6\x96\x87')
print(f.read().decode('utf-8'))
操作文件和目录
Python 内置的os模块可以直接调用系统提供的接口函数操作文件和目录;
>>> import os
>>> os.name
nt
环境变量
os.environ # 全部环境变量 (Class<Environ>)
os.environ.get('key', 'default') # 指定的环境变量,default 可选
操作文件和目录
| 函数 | 作用 | 
|---|---|
| os.path.abspath(‘.’) | 当前路径的绝对路径 | 
| os.path.join(r’d:\a’, ‘b’) | 把路径 2( b)拼接到路径 1(d:\a)上,路径 2 若为绝对路径,直接返回路径 2 | 
| os.mkdir(r’d:\test’) | 创建一个目录 | 
| os.mkdir(r’d:\test’) | 删除一个目录 | 
| os.path.split(r’d:\test\file.txt’) | 拆分成最后级别目录和文件名 | 
| os.path.splitext(r’d:\test\file.txt’) | 拆分下文件扩展名 | 
| os.rename(‘test.txt’, ‘text.py’) | 重命名文件 | 
| os.remove(‘test.py’) | 删除文件 | 
| os.listdir(‘.’) | 列举指定路径 | 
| os.path.isdir(‘d:\test’) | 判断是否路径 | 
| os.path.isfile(‘d:\test\test.txt’) | 判断是否文件 | 
shutil模块对os功能做了补充,其copyfile()提供文件复制功能;
序列化
把变量从内存中变成可存储或传输的过程称为序列化pickling,把序列化对象重新读到内存里称为反序列化unpickling;
Pickle
- dumps/dump
>>> import pickle
>>> d = dict(name='中国人', age=18, score=99)
# pickle.dumps 把任意对象序列化成 bytes
>>> pickle.dumps(d)
b'\x80\x04\x95*\x00\x00\x00\x00\x00\x00\x00}\x94(\x8c\x04name\x94\x8c\t\xe4\xb8\xad\xe5\x9b\xbd\xe4\xba\xba\x94\x8c\x03age\x94K\x12\x8c\x05score\x94Kcu.'
# pickle.dump 直接把对象序列化后写入 file-like Ojbect
>>> with open('dump.txt', 'wb') as w:
...     pickle.dump(d, w)
- loads/load
>>> with open('dump.txt', 'rb') as r:
...     d = pickle.load(r)
...
>>> d
{'name': 'Aurelius', 'age': 18, 'score': 99}
pickle反序列化得到的变量与原来的变量完全无关,只是值相同而已;
pickle序列化只适用于 Python,且不同版本彼此不兼容;
JSON
序列化的一种标准格式,适用于不同编程语言之间传递,标准编码使用 UTF-8;
- JSON 类型关系
| JSON 类型 | Python 类型 | 
|---|---|
| {} | dict | 
| [] | list | 
| string | str | 
| int/float | int/float | 
| true/false | True/False | 
| null | None | 
>>> import json
>>> d = dict(name='Aurelius', age=18, score=99)
>>> json_str = json.dumps(d)
>>> json_str
'{"name": "Aurelius", "age": 18, "score": 99}'
>>> json.loads(json_str)
{'name': 'Aurelius', 'age': 18, 'score': 99}
dumps/dump的ensure_ascii参数可以决定是否统一将返回的str对象编码为ascii字符;
JSON 进阶
自定义类的对象不能直接序列化,需要实现dumps/dump的default参数对应的方法,将该对象转化成dict对象;
json.dumps(o, default=object2dict)
通常class都有__dict__属性,存储着实例的变量(定义了__solts__除外),因此可以直接如此调用;
json.dumps(o, default=lambda o: o.__dict__)
loads/load在反序列化自定义类型时也需传入object_hook相应方法,将dict对象转化为自定义类型的对象;
json.loads(json_str, object_hook=dict2object)
2. 正则表达式
用一种描述性的语言给字符串定义一个规则,用这种规则匹配字符串;
| 描述符 | 作用 | 示例 | 
|---|---|---|
| \d | 匹配数字 | ‘00\d’ 匹配 ‘007’ | 
| \w | 字母或数字 | ‘\w\w\d’ 匹配 ‘py3’ | 
| . | 任意字符 | ‘py.’ 匹配 ‘pyc’、‘py!’ | 
| * | 人一个字符串(包括 0 个) | |
| + | 至少 1 个字符 | |
| ? | 0 个或 1 个字符 | |
| {n} | n 个字符 | ‘\d{3}’ 匹配 ‘010’ | 
| {n,m} | n ~ m 个字符 | ‘\d{3,8}’ 匹配 ‘1234567’ | 
| \ | 转义字符 | ‘\d{3}-\d{3,8}’ 匹配 ‘010-12345’ | 
| \s | 空格、空位符 | 
进阶
| 描述符 | 作用 | 示例 | 
|---|---|---|
| [] | 表示范围 | ‘[0-9a-zA-Z_]’ 匹配任意一个数字、字母或下划线 | 
| A|B | 匹配 A 或 B | |
| ^ | 行的开头 | ‘^\d’ 表示以数字开头 | 
| $ | 行的结束 | ‘\d$’ 表示以数字结束 | 
re 模块
Python 字符串本身用\转义,正则表达式也用\转义,在拼写正则表达式时使用r前缀可以忽略掉 Python 本身字符串的转义;
match
>>> import re
>>> re.match(r'^\d{3}\-\d{3,8}$', '010-12345')
<re.Match object; span=(0, 9), match='010-12345'>
>>> re.match(r'^\d{3}\-\d{3,8}$', '010 12345')
>>>
当匹配成功时,返回一个 Match 对象,否则返回 None;
split
>>> re.split(r'\s+', 'a b   c')
['a', 'b', 'c']
>>> re.split(r'[\s\,\;]+', 'a,b;; c  d')
['a', 'b', 'c', 'd']
通过模式分割字符串,返回分割的数组;
group
>>> m = re.match(r'^(\d{3})-(\d{3,8})$', '010-12345')
>>> m
<re.Match object; span=(0, 9), match='010-12345'>
>>> m.group(2)
'12345'
>>> m.group(1)
'010'
>>> m.group(0)
'010-12345'
通过()提取分组子串,group(0)表示匹配的全部字符串,group(n)表示第 n 个子串;
贪婪匹配
匹配尽可能多的字符
>>> re.match(r'^(\d+)(0*)$', '102300').groups()
('102300', '')
>>> re.match(r'^(\d+)(0+)$', '102300').groups()
('10230', '0')
正则匹配默认是贪婪匹配,想要非贪婪匹配(尽可能少匹配),在\d+后加?;
>>> re.match(r'^(\d+?)(0*)$', '102300').groups()
('1023', '00')
编译
re模块执行步骤:
- 编译正则表达式,不合法则报错;
- 用编译后的正则表达式匹配字符串;
- 预编译
>>> import re
>>> re_telephone = re.compile(r'^(\d{3})-(\d{3,8})$')
>>> re_telephone.match('010-12345').groups()
('010', '12345')
>>> re_telephone.match('010-8086').groups()
('010', '8086')
匹配简单邮箱
def is_valid_email(addr):if re.match(r'(^[a-zA-Z\.]+)\@(gmail|microsoft)\.com$', addr):return Trueelse:return False
匹配带名称邮箱,提取名称
def name_of_email(addr):# 提取邮箱前缀m = re.match(r'^([a-zA-Z\d\s\<\>]+)\@(voyager|example)\.(org|com)$', addr)if not m:return None# 提取前缀中 <> 里面的名称,若不存在,则取全名m = re.match(r'^\<([a-zA-Z\s]+)\>[\s]+[a-zA-Z\d]+|([a-zA-Z\d]+)$', m.group(1))return m.group(1) if m and m.group(1) else m.group(2)
上一篇:「Python 基础」错误、调试与测试
 专栏:《Python 基础》
PS:感谢每一位志同道合者的阅读,欢迎关注、评论、赞!
相关文章:
「Python 基础」I/O 编程、正则表达式
文章目录1. I/O 编程文件读写StringIO 和 BytesIO操作文件和目录序列化2. 正则表达式进阶re 模块1. I/O 编程 I/O指Input/Output; Input Stream 从外面(磁盘、网络)流进内存; Output Stream 从内存流到外面; 同步 …...
java 把pdf图片文档和文章文档转成文字的方法
java 提供了一些库和工具可以用来把 PDF 文档和图片文档转成文本。 Apache PDFBox:这是一个开源的 PDF 库,可以用来提取 PDF 文件中的文本内容。 iText:这是一个用于创建和处理 PDF 文件的库,可以用来提取 PDF 文件中的文本内容。…...
 
JavaScript 中的全部对象
宿主对象(host Objects):由 JavaScript 宿主环境提供的对象,它们的行为完全由宿主环境决定。 【 浏览器环境宿主,全局对象window,window 上又有很多属性,如 document。 全局对象 window 上的属…...
 
【教学典型案例】23.部分服务总是频繁出现掉线情况
目录一:背景介绍问题描述解决二:问题分析过程解决过程设计到的知识1、nacos的data目录作用。2、nacos data目下的protocol目录3、nacos ip混乱问题三:总结一:背景介绍 问题描述 因为某些特殊原因需要把nacos迁移到另一个版本的n…...
 
线程安全 List 效率测试
List 常见类以及各自优缺点可自行参考 https://blog.csdn.net/weixin_39883065/article/details/111197724 本机环境 java 版本:1.8.0_161 window 信息: 测试代码 下面通过代码测试 List 线程安全类 Vector、Collections.synchronizedList(List lis…...
 
LeetCode 热题 C++ 581. 最短无序连续子数组 617. 合并二叉树
581. 最短无序连续子数组 给你一个整数数组 nums ,你需要找出一个 连续子数组 ,如果对这个子数组进行升序排序,那么整个数组都会变为升序排序。 请你找出符合题意的 最短 子数组,并输出它的长度。 示例 1: 输入&am…...
 
鉴源论坛 · 观模丨模型检查综述
作者 | 李建文 华东师范大学软件工程学院博导 版块 | 鉴源论坛 观模 01 模型检查的历史 模型检查是一种起源于20世纪70年代末的形式化验证技术。该技术最初由Edmund M. Clarke、E. Allen Emerson和Joseph Sifakis提出,他们因在模型检查领域的贡献而获得了2007年的…...
 
Easy Deep Learning——池化层
池化是什么?它有什么作用? 还是草地的场景,把草地分成一块块的网格,数量还是太多了,如何继续简化输入数据呢? 这时候可以只取一块网格中所有的小草的大小形状的平均值或者最大值作为一个输入数据,这样就大…...
 
TryHackMe-VulnNet: Active(ez 域渗透)
VulnNet: Active VulnNet Entertainment在他们以前的网络中遇到了不好的时光,该网络遭受了多次破坏。现在,他们移动了整个基础架构,并再次聘请您作为核心渗透测试人员。您的目标是获得对系统的完全访问权限并破坏域。 这应该是我在thm打的最…...
 
TencentOS Server 安装 PostgreSQL
TencentOS 简介 2019 年,随着腾讯公司外部客户的需求,以及公司开源协同战略的推进,tlinux 对外开源并进行了品牌升级,升级为 TencentOS Server。TencentOS 包含三大场景,分别如下: TencentOS Server&…...
 
多线程的风险 --- 线程安全
✨个人主页:bit me👇 ✨当前专栏:Java EE初阶👇 ✨每日一语:低头赶路,敬事如仪;自知自心,其路则明。 目 录🍸一. 线程不安全🍹二. 线程不安全的原因…...
 
Linux信号详解
文章目录Linux信号什么是信号**从生活角度理解: **技术应用角度的信号进程的注意事项信号概念用kill -l命令可以察看系统定义的信号列表信号处理常见方式概览信号产生通过终端按键产生信号使用signal函数自定义SIGINT信号的处理方式使用sigprocmask函数阻塞2号信号和40号信号vo…...
JAVA使用POI操作EXCEL
设置公式totalRow.createCell(4).setCellFormula("SUM(E9:E35");// 执行公式wb.setForceFormulaRecalculation(true);合并单元格sheet.addMergedRegion(new CellRangeAddress(0, 0, 3, 7));单元格格式CellStyle cellStyle wb.createCellStyle();// 字体XSSFFont fon…...
 
只做笔记有必要买apple pencil吗?苹果笔的代替笔推荐
如果仅仅使用IPAD来进行打游戏和看剧的话,未免有些浪费。ipad的作用还是挺大的,可以用来做学习笔记,也可以用来做绘画,也可以用来做一些重要的内容。很多人都会认为,苹果的电容笔很好用,但是价格上要比一般…...
 
Hive---sqoop安装教程及sqoop操作
sqoop安装教程及sqoop操作 文章目录sqoop安装教程及sqoop操作上传安装包解压并更名添加jar包修改配置文件添加sqoop环境变量启动sqoop操作查看指定mysql服务器数据库中的表在hive中创建一个teacher表跟mysql的mysql50库中的teacher结构相同将mysql中mysql50库中的sc数据导出到h…...
 
【C++】register 关键字
文章目录一. 什么是寄存器?二. 为什么要存在寄存器?三. register 修饰变量一. 什么是寄存器? 我们都知道,CPU主要是负责进行计算的硬件单,但是为了方便运算,一般第一步需要先把数据从内存读取到CPU内&…...
 
剑指 Offer II 024. 反转链表
题目链接 剑指 Offer II 024. 反转链表 easy 题目描述 给定单链表的头节点 head,请反转链表,并返回反转后的链表的头节点。 示例 1: 输入:head [1,2,3,4,5] 输出:[5,4,3,2,1] 示例 2: 输入:h…...
 
从Linux内核中学习高级C语言宏技巧
Linux内核可谓是集C语言大成者,从中我们可以学到非常多的技巧,本文来学习一下宏技巧,文章有点长,但耐心看完后C语言level直接飙升。 本文出自:大叔的嵌入式小站,一个简单的嵌入式/单片机学习、交流小站 从…...
详解Python的装饰器
Python中的装饰器是你进入Python大门的一道坎,不管你跨不跨过去它都在那里。 为什么需要装饰器 我们假设你的程序实现了say_hello()和say_goodbye()两个函数。 def say_hello():print "hello!"def say_goodbye():print "hello!" # bug hereif…...
 
k8s-Pod域名学习总结
k8s-Pod域名学习总结 大纲 k8s内置DNS服务 配置Pod的域名服务 CornDNS配置 默认Pod的域名 自定义Pod的域名 实战需求 1 Pod有自己的域名 2 集群内部的Pod可以通过域名访问其他的Pod 基础准备: 1 k8s 集群版本1.17 k8s内置DNS服务 k8s1.17安装完成后自动创建…...
Python|GIF 解析与构建(5):手搓截屏和帧率控制
目录 Python|GIF 解析与构建(5):手搓截屏和帧率控制 一、引言 二、技术实现:手搓截屏模块 2.1 核心原理 2.2 代码解析:ScreenshotData类 2.2.1 截图函数:capture_screen 三、技术实现&…...
三维GIS开发cesium智慧地铁教程(5)Cesium相机控制
一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点: 路径验证:确保相对路径.…...
 
vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...
 
Linux --进程控制
本文从以下五个方面来初步认识进程控制: 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程,创建出来的进程就是子进程,原来的进程为父进程。…...
 
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问(基础概念问题) 1. 请解释Spring框架的核心容器是什么?它在Spring中起到什么作用? Spring框架的核心容器是IoC容器&#…...
 
并发编程 - go版
1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...
 
Chromium 136 编译指南 Windows篇:depot_tools 配置与源码获取(二)
引言 工欲善其事,必先利其器。在完成了 Visual Studio 2022 和 Windows SDK 的安装后,我们即将接触到 Chromium 开发生态中最核心的工具——depot_tools。这个由 Google 精心打造的工具集,就像是连接开发者与 Chromium 庞大代码库的智能桥梁…...
 
[论文阅读]TrustRAG: Enhancing Robustness and Trustworthiness in RAG
TrustRAG: Enhancing Robustness and Trustworthiness in RAG [2501.00879] TrustRAG: Enhancing Robustness and Trustworthiness in Retrieval-Augmented Generation 代码:HuichiZhou/TrustRAG: Code for "TrustRAG: Enhancing Robustness and Trustworthin…...
