2. 包(Packages)
2.1 包的定义和作用
定义
-
包是将模块以文件夹的组织形式进行分组管理的方法,以便更好地组织和管理相关模块。
-
包是一个包含一个特殊的
__init__.py
文件的目录,这个文件可以为空,但必须存在,标识目录为Python包。 -
包可以包含子包(子目录)和模块,可以使用点表示法来导入。
作用
-
将一系列模块进行分类管理,有利于防止命名冲突
-
可以在需要时加载一个或部分模块而不是全部模块
包示例:
mypack/__init__.pymenu.py # 菜单管理模块games/__init__.pycontra.py # 魂斗罗supermario.py # 超级玛丽 mariotanks.py # 坦克大作战office/__init__.pyexcel.pyword.pypowerpoint.py
2.2 导入包和子包
-
使用
import
关键字可以导入包和子包,以访问其中的模块和内容。
# 同模块的导入规则import 包名 [as 包别名]import 包名.模块名 [as 模块新名]import 包名.子包名.模块名 [as 模块新名]from 包名 import 模块名 [as 模块新名]from 包名.子包名 import 模块名 [as 模块新名]from 包名.子包名.模块名 import 属性名 [as 属性新名]# 导入包内的所有子包和模块from 包名 import *from 包名.模块名 import *
参考案例:
# 导入包中的模块 import matplotlib.pyplot as plt # 导入子包中的模块 from sklearn.linear_model import LinearRegression
2.3 使用包和子包
-
使用导入的包和模块的内容,可以通过包名和点表示法来访问。
参考案例:
# 使用包中的模块 import pandas as pd data_frame = pd.DataFrame() # 使用子包中的模块 from tensorflow.keras.layers import Dense
2.4 __init__.py
文件
__init__.py
文件的主要作用是用于初始化Python包(package)或模块(module),它可以实现以下功能:
-
标识包目录: 告诉Python解释器所在的目录应被视为一个包或包含模块的包。没有这个文件,目录可能不会被正确识别为包,导致无法导入包内的模块。
-
执行初始化代码: 可以包含任何Python代码,通常用于执行包的初始化操作,如变量初始化、导入模块、设定包的属性等。这些代码在包被导入时会被执行。
-
控制包的导入行为: 通过定义
__all__
变量,可以明确指定哪些模块可以被从包中导入,从而限制包的公开接口,防止不需要的模块被导入。 -
提供包级别的命名空间:
__init__.py
中定义的变量和函数可以在包的其他模块中共享,提供了一个包级别的命名空间,允许模块之间共享数据和功能。 -
批量导入模块: 可以在
__init__.py
文件中批量导入系统模块或其他模块,以便在包被导入时,这些模块可以更方便地使用。
以下是一个简单的 __init__.py
文件的代码示例,演示了上述功能的使用:
# __init__.py 文件示例 # 1. 批量导入系统模块 import os import sys import datetime # 2. 定义包级别的变量 package_variable = "This is a package variable" # 3. 控制包的导入行为 __all__ = ['module1', 'module2'] # 4. 执行初始化代码 print("Initializing mypackage") # 注意:这个代码会在包被导入时执行 # 5. 导入包内的模块 from . import module1 from . import module2
在这个示例中,__init__.py
文件用于批量导入系统模块、定义包级别的变量、控制包的导入行为、执行初始化代码,以及导入包内的模块。这有助于包的组织、初始化和导入管理。
3. 第三方包
Python第三方包是由Python社区开发的,可用于扩展Python功能和解决各种问题的软件包。这些包提供了各种各样的功能,包括数据分析、机器学习、网络编程、Web开发、图形处理、自然语言处理等。
3.1 安装和使用
-
使用pip:pip是Python的包管理工具,用于安装、升级和管理第三方包。确保你的Python安装中包含了pip。
-
安装第三方包:
-
使用pip安装包:在命令行中运行以下命令来安装包,将"package-name"替换为要安装的包的名称。
pip install package-name
-
安装特定版本的包:如果你需要安装特定版本的包,可以使用以下命令:
pip install package-name==version
-
通过镜像安装,可以使用以下命令:
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple package1 package2 package3 ...
-
从requirements文件安装:你可以将要安装的包及其版本记录在一个文本文件中,通常命名为requirements.txt,然后运行以下命令安装其中列出的所有包:
pip install -r requirements.txt
-
-
导入包:在Python脚本或交互式环境中,使用
import
语句导入已安装的包,以便在代码中使用它们。import package_name
-
使用包:每个第三方包都有不同的用法和功能,通常伴随着官方文档和示例代码。你可以查阅官方文档,或者使用
help()
函数来了解包的功能和方法。示例:import package_name help(package_name)
-
更新和卸载包:
-
更新包:使用以下命令来更新已安装的包:
pip install --upgrade package-name
-
卸载包:如果你想卸载包,可以使用以下命令:
pip uninstall package-name
-
3.2 依赖清单
可以使用pipreqs来维护requirements.txt文件,以便轻松地重建环境。
pipreqs
是一个用于管理Python项目依赖清单的工具,它会自动分析项目代码,并生成requirements.txt
文件,列出项目所需的所有依赖包及其版本。以下是使用pipreqs
管理依赖清单的步骤:
安装pipreqs:
如果你还没有安装pipreqs
,可以使用pip安装它(比较慢,可能会丢包):
pip install pipreqs
在项目目录中运行pipreqs:
进入你的项目目录,然后运行以下命令:
pipreqs .
这会分析项目代码,并在当前目录下生成一个名为requirements.txt
的文件,其中包含了项目所需的所有依赖包及其版本。
如果遇到编码错误UnicodeDecodeError,则将指定编码为utf8:
pipreqs ./ --encoding=utf8 pipreqs ./ --encoding=gbk pipreqs ./ --encoding='iso-8859-1'
查看生成的requirements.txt文件:
打开requirements.txt
文件,你将看到列出的依赖包及其版本,类似于以下内容:
package1==1.0.0 package2==2.1.3 ...
选择是否要修改requirements.txt文件:
pipreqs
生成的requirements.txt
文件可能包含一些不必要的依赖,或者可能需要手动指定特定版本。
你可以编辑requirements.txt
文件,根据项目的需要添加、删除或修改依赖项。
-
安装依赖:
一旦你准备好了
requirements.txt
文件,你可以使用pip
来安装项目的依赖:pip install -r requirements.txt
-
定期更新依赖:
定期使用
pipreqs
重新生成requirements.txt
文件,以确保依赖清单保持最新。你可以使用以下命令:pipreqs .
pipreqs
是一个方便的工具,它可以帮助你自动创建和维护项目的依赖清单。不过,需要记住,生成的依赖清单可能包含一些不必要的依赖,因此你应该仔细检查和编辑requirements.txt
文件以确保它反映了项目的真实需求。
Python的包和模块是组织、管理和重用代码的重要工具。它们有助于将代码划分为可管理的单元,提高了代码的可读性和可维护性。通过模块和包,你可以更有效地组织项目,减少命名冲突,以及在不同项目之间重用代码,从而更轻松地进行Python编程。
Python异常
-
作用
用作信号通知,通知上层调用者有错误产生需要处理
1. try 语句
-
语法
try:可能发生异常的语句块 except 错误类型1 [as 变量名1]:异常处理语句块1 except 错误类型2 [as 变量名2]:异常处理语句块2 ... except 错误类型n [as 变量名n]:异常处理语句块n except:异常处理语句块other else:未发生异常的语句 finally:最终的处理语句
-
作用
尝试捕获异常,得到异常通知,将程序由异常状态变为正常状态
-
说明
except 子句可以有 1个或多个
except: 不给错误类型,可以匹配全部的错误类型
else 子句里的语句会在 没有错误发生时执行,当处于异常时不执行
finally 子句里的语句,无论何时都执行
-
示例
try:x = int(input("请输入一个整数:"))print('x=', x) except ValueError:print('您的输入不能转成整数') print("程序结束")
#try except:
#try模块中的是可能会出现异常的代码
#except:如果try模块中的代码执行出现异常,则由except模块捕获,然后处理异常
#finally:不管try模块中的代码是否出现异常,finally模块中的代码始终都会执行
def exception_test():try:b = 1 / 0except ZeroDivisionError as e:print(f'除数不能为0:{e}')#finally:print('run finally')
if __name__ == '__main__':exception_test()
2. raise 语句
-
问题
# 写一个函数, get_score 函数,读取用户输入的整数成绩, # 成绩的正常值是0~100 之间, 要求, 如果不在0~100 之间 # 报 ValueError类型的错误 def get_score():x = int(input('请输入成绩:'))if 0 <= x <= 100:return xraise ValueError
-
语法
raise 异常类型 或 raise 异常对象
-
作用
-
抛出一个错误,让程序进入异常状态
-
发送错误通知给调用者
-
-
示例:
## 写一个函数, get_score 函数,读取用户输入的整数成绩, ## 成绩的正常值是0~100 之间, 要求, 如果不在0~100 之间 ## 报 ValueError类型的错误 def get_score():x = int(input('请输入成绩:'))if 0 <= x <= 100:return x# raise ValueErrorraise ValueError('用户输入的成绩不在 0~100 之间') try:score = get_score()print(score) except ValueError as err:print("成绩输入有误 err=", err)
err的作用就是接收raise ValueError('用户输入的成绩不在 0~100 之间')给出的提示信息
-
异常类型的可选种类
详见:
>>> help(__builtins__)
#raise:在代码出现异常的时候,向外抛异常信息 #先判断代码中是否会出现异常,如果会出现则向外抛异常,三思而后行 #try不判断代码是否出现异常,当代码出现异常时通过except捕获,先执行再捕获 def raise_test(a,b):if b==0:raise Exception('除数不能为0')return a/b if __name__ == '__main__':c=raise_test(1,0)print(c)
-
课后练习1
写一个猜拳游戏: 石头,剪刀,布, 让电脑随机生成一个, 你的输入如下:0) 石头1) 剪刀2) 布q) 退出请选择: 0电脑出的是 布 ,你输了 循环输入,知道输入q 为止
参考答案1
import random import time signal = ['石头', '剪刀', '布'] def show_menu():print(" 0) 石头 ")print(" 1) 剪刀 ")print(" 2) 布 ")print(" q) 退出 ") def begin_compare(computer, your):comp_s = signal[computer] # 电脑的字符串your_s = signal[your]print('电脑出的是', comp_s, '你出的是', your_s)if comp_s == your_s:print('平局!')elif comp_s == '石头':if your_s == '剪刀':print('你输了!')elif your_s == '布':print('你赢了!')elif comp_s == '剪刀':if your_s == '布':print('你输了!')elif your_s == '石头':print('你赢了!')elif comp_s == '布':if your_s == '石头':print('你输了!')elif your_s == '剪刀':print('你赢了!')# time.sleep(5)input('请输入回车键,继续下一次猜拳:') def run():'''开始猜拳游戏'''while True:show_menu()s = input('请选择:')if s == 'q':breakyour = int(s) # 你的选项computer = random.randint(0, 2)begin_compare(computer, your) if __name__ == '__main__':run()
参考答案2
import random import time signal = ['石头', '剪刀', '布'] result = ['平局!', '你赢了!', '你输了!']# 0 1 -1 # 定义一个二维列表, 行代表 电脑的选择, 列代表我的选择 map = [# 用户: 0 1 2[ 0, -1, 1], # 电脑出的是0---> 石头[ 1, 0, -1], # 电脑出的是1---> 剪刀[-1, 1, 0], # 电脑出的是2---> 布 ] def show_menu():print(" 0) 石头 ")print(" 1) 剪刀 ")print(" 2) 布 ")print(" q) 退出 ") def begin_compare(computer, your):comp_s = signal[computer] # 电脑的字符串your_s = signal[your]print('电脑出的是', comp_s, '你出的是', your_s)result_index = map[computer][your]r = result[result_index]print(r)# time.sleep(5)input('请输入回车键,继续下一次猜拳:') def run():'''开始猜拳游戏'''while True:show_menu()s = input('请选择:')if s == 'q':breakyour = int(s) # 你的选项computer = random.randint(0, 2)begin_compare(computer, your) if __name__ == '__main__':run()
-
课后练习2
写一个猜数字游戏 让电脑随机生成一个 0 ~ 100 的整数让用来猜 如果 您输入的数大于电脑生产的数,提示:“您猜大了”, 继续猜 如果 您输入的数小于电脑生产的数,提示:“您猜小了”, 继续猜 当 您输入的数等于电脑生产的数,提示:"恭喜您猜对了" 打印猜的次数后退出程序
参考答案
import random def run():# 1. 让电脑生成一个整数,用 x 变量绑定x = random.randint(0, 100)count = 0 # 记次数while True:y = int(input('请输入: '))count += 1if y > x:print('您猜大了!')elif y < x:print('您猜小了!')else:print('恭喜您猜对了!')breakprint('您共猜了', count, '次') if __name__ == '__main__':run()
3.Python全部的错误类型
错误类型 | 说明 |
---|---|
ZeroDivisionError | 除(或取模)零 (所有数据类型) |
ValueError | 传入无效的参数 |
AssertionError | 断言语句失败 |
StopIteration | 迭代器没有更多的值 |
IndexError | 序列中没有此索引(index) |
IndentationError | 缩进错误 |
OSError | 输入/输出操作失败 |
ImportError | 导入模块/对象失败 |
NameError | 未声明/初始化对象 (没有属性) |
AttributeError | 对象没有这个属性 |
<!-- 以下不常用 --> | |
GeneratorExit | 生成器(generator)发生异常来通知退出 |
TypeError | 对类型无效的操作 |
KeyboardInterrupt | 用户中断执行(通常是输入^C) |
OverflowError | 数值运算超出最大限制 |
FloatingPointError | 浮点计算错误 |
BaseException | 所有异常的基类 |
SystemExit | 解释器请求退出 |
Exception | 常规错误的基类 |
StandardError | 所有的内建标准异常的基类 |
ArithmeticError | 所有数值计算错误的基类 |
EOFError | 没有内建输入,到达EOF 标记 |
EnvironmentError | 操作系统错误的基类 |
WindowsError | 系统调用失败 |
LookupError | 无效数据查询的基类 |
KeyError | 映射中没有这个键 |
MemoryError | 内存溢出错误(对于Python 解释器不是致命的) |
UnboundLocalError | 访问未初始化的本地变量 |
ReferenceError | 弱引用(Weak reference)试图访问已经垃圾回收了的对象 |
RuntimeError | 一般的运行时错误 |
NotImplementedError | 尚未实现的方法 |
SyntaxError Python | 语法错误 |
TabError | Tab 和空格混用 |
SystemError | 一般的解释器系统错误 |
UnicodeError | Unicode 相关的错误 |
UnicodeDecodeError | Unicode 解码时的错误 |
UnicodeEncodeError | Unicode 编码时错误 |
UnicodeTranslateError | Unicode 转换时错误 |
以下为警告类型 | |
Warning | 警告的基类 |
DeprecationWarning | 关于被弃用的特征的警告 |
FutureWarning | 关于构造将来语义会有改变的警告 |
OverflowWarning | 旧的关于自动提升为长整型(long)的警告 |
PendingDeprecationWarning | 关于特性将会被废弃的警告 |
RuntimeWarning | 可疑的运行时行为(runtime behavior)的警告 |
SyntaxWarning | 可疑的语法的警告 |
UserWarning | 用户代码生成的警告 |
详见:help(builtins)
课后练习
写一个函数 get_age() 用来获取一个人的年龄信息此函数规定用户只能输入1~140之间的整数,如果用户输入其它的数则直接触发ValueError类型的错误! def get_age():... try:age = get_age()print("用户输入的年龄是:", age) except ValueError as err:print("用户输入的不是1~140的整数,获取年龄失败!")
参考答案
def get_age():age = int(input('请输入: '))if age < 0 or age > 140:raise ValueError("年龄范围错误")return age
Python文件操作
文件操作是Python中常见的任务之一,用于创建、读取、写入和管理文件。以下是一些常见的文件操作任务的思路、总结和示例代码:
1. 打开文件
要执行文件操作,首先需要打开文件。使用open()
函数可以打开文件,指定文件名以及打开模式(读取、写入、追加等)。
# 打开一个文本文件以读取内容 file = open("example.txt", "r")
2. 读取文件
一旦文件被打开,可以使用不同的方法来读取文件内容。
# 读取整个文件内容 content = file.read() # 逐行读取文件内容 for line in file: #直接遍历文件对象,每次读取一行。这种方式更内存友好,因为不需要将所有行读入内存。print(line)
with open('example.txt', 'r') as file:lines = file.readlines() # 读取文件的所有行,并将其作为一个列表返回。for line in lines:print(line, end='') 代码和file = open("example.txt", "r")for line in file:print(line) 代码的区别
3. 写入文件
要写入文件,需要打开文件以写入模式('w'),然后使用write()
方法。
# 打开文件以写入内容 file = open("example.txt", "w") # 写入内容 file.write("这是一个示例文本。")
4. 关闭文件
完成文件操作后,应该关闭文件,以释放资源和确保文件的完整性。
file.close()
5. 使用with
更安全的方法是使用with
语句,它会自动关闭文件。
with open("example.txt", "r") as file:content = file.read()# 文件自动关闭
6. 检查是否存在
可以使用os.path.exists()
来检查文件是否存在。
import os if os.path.exists("example.txt"):print("文件存在")
7. 处理异常
在文件操作中,可能会出现各种异常情况,例如文件不存在或没有权限。在文件操作中捕获这些异常是个好习惯。
try:with open("example.txt", "r") as file:content = file.read() except FileNotFoundError:print("文件不存在") except Exception as e:print(f"发生错误:{e}")
这些是文件操作的一些常见思路和示例代码。请根据你的具体需求和场景来调整代码。在进行文件操作时,要确保小心处理文件,以避免意外数据损坏或文件损坏。
除了打开、读取和写入文件之外,还有一些其他常见的文件操作,如复制、删除和改变文件名。以下是这些操作的思路和示例代码:
8. 复制文件
要复制文件,你可以使用shutil
模块的copy
方法。
import shutil source_file = "source.txt" destination_file = "destination.txt" shutil.copy(source_file, destination_file)
9. 删除文件
要删除文件,可以使用os
模块的remove
方法。
import os file_to_delete = "file_to_delete.txt" if os.path.exists(file_to_delete):os.remove(file_to_delete)print(f"{file_to_delete} 已删除") else:print(f"{file_to_delete} 不存在")
10. 修改名称
要改变文件名,可以使用os
模块的rename
方法。
import os old_name = "old_name.txt" new_name = "new_name.txt" if os.path.exists(old_name):os.rename(old_name, new_name)print(f"文件名已更改为 {new_name}") else:print(f"{old_name} 不存在")
def file_demo():f=open('../test.txt','a+')print(f)#print(f.read())line = f.readline()while line:print(line)line=f.readline()
s='zxc'#f.write(s)f.writelines(s)
with open('../requirements','r') as f:print(f.read())
shutil.copy('../test.txt','../test1.txt')os.remove('../test1.txt')
if __name__ == '__main__':file_demo()
Python JSON 数据解析
JSON(JavaScript Object Notation)是一种轻量级数据交换格式,它易于阅读和编写,同时也易于机器解析和生成。Python提供了内置的JSON模块,用于处理JSON数据。
1. 导入模块
import json
2. 序列化
import json data = {"name": "John","age": 30,"city": "New York" } json_str = json.dumps(data) # json.dumps() 是 Python 的 json 模块中的一个函数,它的作用是将 Python 对象转换为 JSON 格式的字符串。 print(json_str)
3. 反序列化
json_str = '{"name": "John", "age": 30, "city": "New York"}' data = json.loads(json_str) # json.loads() 是 Python json 模块中的一个函数,它的作用是将 JSON 格式的字符串转换为 Python 对象。 print(data)
4. 对象存文件
data = {"name": "John","age": 30,"city": "New York" } with open('data.json', 'w') as json_file:json.dump(data, json_file)
5. 从文件加载
with open('data.json', 'r') as json_file:data = json.load(json_file)print(data)
6. 嵌套JSON数据
如果JSON数据包含嵌套结构,您可以使用递归来访
问和修改其中的值。
json_data = {"name": "Alice","info": {"age": 25,"location": "Paris"} } # 获取嵌套的值 age = json_data["info"]["age"] # 修改嵌套的值 json_data["info"]["location"] = "New York" # 将更改后的数据转换为JSON字符串 new_json_str = json.dumps(json_data)
7. JSON中列表
JSON可以包含列表,可以使用索引来访问列表元素。
json_data = {"fruits": ["apple", "banana", "cherry"] } # 获取列表中的第一个水果 first_fruit = json_data["fruits"][0] # 添加一个新水果到列表 json_data["fruits"].append("orange")
8. JSON中空值
JSON允许表示空值(null),在Python中,它通常转换为None
。
json_data = {"value": None }
字典和JSON格式不同之处
-
数据类型限制:
-
JSON:支持的数据类型包括对象(类似于字典)、数组(类似于列表)、字符串、数字、布尔值和
null
。JSON 不支持 Python 特有的数据类型如tuple
、set
、bytes
等。 -
Python 字典:可以包含多种 Python 特有的数据类型,比如
tuple
、set
、bytes
等。
-
-
格式要求:
-
JSON:数据必须以字符串的形式表示,键必须是双引号括起来的字符串,值可以是字符串、数字、布尔值、数组、对象或
null
。 -
Python 字典:键可以是任意不可变的类型(如字符串、数字、元组),值可以是任意类型。键通常用单引号或双引号括起来,但 Python 允许在字典中使用不加引号的键。
-
# json结构:以{}作为开始和结尾,其中数据格式为key:value,多个key:value之间用英文逗号分隔
#json以键值对(key:value)组成的,key必须是字符串类型,value可以是任意类型
#json一旦生成json字符串后不能修改,如果要修改,需要反序列化(loads)成字典对象进行修改
def json_demo():data={'name':'zhangsan','age':20,'address':'四川省'}#dumps:json序列化,转化为json字符串json_str=json.dumps(data)print(json_str)
#loads:将json字符串转换为字典对象data1=json.loads(json_str)print(data1)#dump:将json存入文件,文件需要先用open打开,生成一个file对象json.dump(data,open('test.json','w'))
#load:从文件中读取json,文件需要先打开#dump和load是做json文件的读写#dumps和loads是做json的序列化和反序列化with open('test.json','r')as f:data2=json.load(f)print(data2)
data3={'name':'zhangsan','info':{'age':20,'address':'sichuan'}}
name=data3['name']print(name)age=data3['info']['age']print(age)
data4={'name':'zhangsan','score':[20,30,40,50],'info':{'hobby':['basketball','football']}}score=data4['score'][1]print(score)hobby=data4['info']['hobby'][-1]print(hobby)
#如果定义json某个字段为空值,在python中使用None#将json转换为字符串后该空值(None)自动转换为nulldata5={'name':'zhangsan','score':None}
js=json.dumps(data5)print(js)#{'name':'zhangsan','score':null}if __name__ == '__main__':json_demo()
Python正则表达式
正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。re模块使 Python 语言拥有全部的正则表达式功能。正则表达式在网络爬虫、数据分析中有着广泛使用,掌握正则表达式能够达到事半功倍的效果。
模式 | 描述 |
---|---|
^ | 匹配字符串的开头 |
$ | 匹配字符串的末尾。 |
. | 匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符。 |
[…] | 用来表示一组字符,单独列出:[amk] 匹配 'a','m'或'k' |
[^…] | 不在[]中的字符:abc 匹配除了a,b,c之外的字符。 |
re* | 匹配0个或多个的表达式。 |
re+ | 匹配1个或多个的表达式。 |
re? | 匹配0个或1个由前面的正则表达式定义的片段,非贪婪方式 |
re{n} | 匹配n个前面表达式。例如,"o{2}"不能匹配"Bob"中的"o",但是能匹配"food"中的两个o。 |
re{n,} | 精确匹配n个前面表达式。例如,"o{2,}"不能匹配"Bob"中的"o",但能匹配"foooood"中的所有o。"o{1,}"等价于"o+"。"o{0,}"则等价于"o*"。 |
re{n, m} | 匹配 n 到 m 次由前面的正则表达式定义的片段,贪婪方式 |
| | 匹配a或b |
(re) | 匹配括号内的表达式,也表示一个组 |
(?imx) | 正则表达式包含三种可选标志:i, m, 或 x 。只影响括号中的区域。 |
(?-imx) | 正则表达式关闭 i, m, 或 x 可选标志。只影响括号中的区域。 |
(?: re) | 类似 (...), 但是不表示一个组 |
(?imx: re) | 在括号中使用i, m, 或 x 可选标志 |
(?-imx: re) | 在括号中不使用i, m, 或 x 可选标志 |
(?#...) | 注释. |
(?= re) | 前向肯定界定符。如果所含正则表达式,以 ... 表示,在当前位置成功匹配时成功,否则失败。但一旦所含表达式已经尝试,匹配引擎根本没有提高;模式的剩余部分还要尝试界定符的右边。 |
(?! re) | 前向否定界定符。与肯定界定符相反;当所含表达式不能在字符串当前位置匹配时成功。 |
(?> re) | 匹配的独立模式,省去回溯。 |
\w | 匹配数字字母下划线 |
\W | 匹配非数字字母下划线 |
\s | 匹配任意空白字符,等价于 [\t\n\r\f]。 |
\S | 匹配任意非空字符 |
\d | 匹配任意数字,等价于 [0-9]。 |
\D | 匹配任意非数字 |
\A | 匹配字符串开始 |
\Z | 匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串。 |
\z | 匹配字符串结束 |
\G | 匹配最后匹配完成的位置。 |
\b | 匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。 |
\B | 匹配非单词边界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。 |
\n, \t, 等 | 匹配一个换行符。匹配一个制表符, 等 |
\1...\9 | 匹配第n个分组的内容。 |
\10 | 匹配第n个分组的内容,如果它经匹配。否则指的是八进制字符码的表达式。 |
1.字符匹配
方法和功能
方法 | 功能 |
---|---|
match() | 判断一个正则表达式是否从开始处匹配一个字符串 |
search() | 遍历字符串,找到正则表达式匹配的第一个位置,返回匹配对象 |
findall() | 遍历字符串,找到正则表达式匹配的所有位置,并以列表的形式返回。如果给出的正则表达式中包含子组,就会把子组的内容单独返回,如果有多个子组就会以元组的形式返回。 |
finditer() | 遍历字符串,找到正则表达式匹配的所有位置,并以迭代器的形式返回 |
特殊字符 | 含义 |
---|---|
\d | 匹配任何十进制数字;相当于类 [0-9] |
\D | 与 \d 相反,匹配任何非十进制数字的字符;相当于类 0-9 |
\s | 匹配任何空白字符(包含空格、换行符、制表符等);相当于类 [ \t\n\r\f\v] |
\S | 与 \s 相反,匹配任何非空白字符;相当于类 \t\n\r\f\v |
\w | 匹配任意一个文字字符,包括大小写字母、数字、下划线,等价于表达式[a-zA-Z0-9_] |
\W | 于 \w 相反 (注:re.ASCII 标志使得 \w 只能匹配 ASCII 字符) |
\b | 匹配单词的开始或结束 |
\B | 与 \b 相反 |
-
\w 匹配字母数字下划线(汉字)
-
\d匹配数字
import re text="hqyj66d6 a1h43d3fd43s43d4 " data=re.findall("d\d",text) # 只匹配一个数字 print(data)#['d6', 'd3', 'd4', 'd4']
import re text="hqyj66d6 a1h43d3fd43s43d4 " data=re.findall("d\d+",text) print(data)#['d6', 'd3', 'd43', 'd4']
-
\s匹配任意空白符 包括空格,制表符等等
import re text="hqyj666 jack karen 666" data=re.findall("\sj\w+\s",text) print(data)#[' jack ']
2.数量控制
*重复0次或者更多次
+重复1次或者更多次
?重复1次或者0次
{n}重复n次,n是数字
{n,}重复n次或者更多次
{n,m}重复n到m次
3.分组
-
()提取兴趣区域
import re text="谢帝谢帝,我要迪士尼,我的电话号码18282832341,qq号码1817696843" data=re.findall("号码(\d{10,})",text) print(data)#['18282832341', '1817696843']
import re text="谢帝谢帝,我要迪士尼,我的电话号码18282832341,qq号码1817696843" data=re.findall("(\w{2}号码(\d{10,}))",text) print(data)#['18282832341', '1817696843']
-
(|)提取兴趣区域(| = or)
import re text="第一名张三 第一名物理149分 第一名数学150分 第一名英语148分 第一名总分740分" data=re.findall("第一名(\w{2,}|\w{2,}\d{2,}分)",text) print(data)#['张三', '物理149分', '数学150分', '英语148分', '总分740分']
4.开始和结束
-
^开始
import re text = "hqyj66abc hqyj123" data = re.findall("^hqyj\d+", text) print(data) #['hqyj66']
-
$结尾
import re text = "hqyj66abc hqyj123" data = re.findall("hqyj\d+$", text) print(data) #['hqyj123']
5.特殊字符
由于正则表达式中* . \ {} () 等等符号具有特殊含义,如果你指定的字符正好就是这些符号,需要用\进行转义
import re text = "数学中集合的写法是{2}" data = re.findall("\{2\}", text) print(data) #['{2}']
6.re模块的常用方法
re.findall
获取匹配到的所有数据
import re text="hqyj66d6 a1h43d3fd43s43d4 " data=re.findall("d\d+",text) print(data)#['d6', 'd3', 'd43', 'd4']
re.match
从字符串的起始位置匹配,成功返回一个对象否则返回none。
匹配成功返回对象,对象的方法:
方法 | 功能 |
---|---|
group() | 返回匹配的字符串 |
start() | 返回匹配的开始位置 |
end() | 返回匹配的结束位置 |
span() | 返回一个元组表示匹配位置(开始,结束) |
import re # 在起始位置匹配,并返回一个包含匹配 (开始,结束) 的位置的元组 print(re.match('www', "www.python.com").span())#(0, 3) print(re.match('www', "www.python.com").start())#0 print(re.match('www', "www.python.com").end())#3 # 不在起始位置匹配 print(re.match('com', "www.python.com"))# None
re.search
扫描整个字符串并返回第一个成功匹配的字符串。成功返回一个对象否则返回none
import re # 在起始位置匹配 print(re.search('www', 'www.hqyj.com').span())#(0, 3) # 不在起始位置匹配 print(re.search('com', 'www.hqyj.com').span())#(9, 12)
re.sub
替换匹配成功的字符
类似与字符串的replace函数
import re text = "以前华清远见在四川大学旁边,现在华清远见在西南交大旁边" data = re.sub("华清远见","北京华清远见科技集团成都中心", text) print(data)#以前北京华清远见科技集团成都中心在四川大学旁边,现在北京华清远见科技集团成都中心在西南交大旁边
re.split
根据匹配成功的位置对字符串进行分割
import re text = "python is very easy" data = re.split("\s{1,}", text) print(data)#['python', 'is', 'very', 'easy']
re.finditer
类似findall 但是不会全部返回出来 而是返回迭代器(比如匹配成功了10万个 全部返回就很吃内存了)
import re text = "python is very easy" data = re.findall("\w+", text) print(data)#['python', 'is', 'very', 'easy']
import re text = "python is very easy" data = re.finditer("\w+", text) print(data) for el in data:print(el.group())
7.常见的一些正则
QQ号:[1 - 9][0 - 9]{4, }(腾讯QQ号从10000开始) 帐号(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$ 手机号码:^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$ Email地址:^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$ 密码(以字母开头,长度在6~18之间,只能包含字母、数字和下划线):^[a-zA-Z]\w{5,17}$ 身份证号(15位、18位数字):^\d{15}|\d{18}$ 短身份证号码(数字、字母x结尾):^([0-9]){7,18}(x|X)?$ 或 ^\d{8,18}|[0-9x]{8,18}|[0-9X]{8,18}?$
Python日期和时间
Python 的 time 模块下有很多函数可以转换
-
常见日期格式。
time 模块时间处理的和转换时间格式的常用API: 官网链接
time.time() - 获取当前时间的时间戳(以秒为单位,浮点数形式,精确到小数点后若干位)
import time # 引入time模块 ticks = time.time() print ("当前时间戳为:", ticks)#时间戳单位最适于做日期运算。但是1970年之前的日期就无法以此表示了。太遥远的日期也不行,UNIX和Windows只支持到2038年
time.sleep(secs) - 让程序暂停执行指定秒数。
import time # 让程序暂停3秒 time.sleep(3) print("3秒后执行到这里...")
time.ctime(timestamp=None) - 将时间戳转换为易读的本地时间格式。
import time # 获取当前时间的ctime格式 current_time = time.ctime() print("当前时间 (ctime):", current_time) # 或者使用特定时间戳 timestamp = 1647708000 # 这是一个示例时间戳 converted_time = time.ctime(timestamp) print("时间戳转ctime格式:", converted_time)
time.localtime([secs]) - 将时间戳转换为本地时区的struct_time元组。
import time # 获取当前时间的struct_time元组 local_time_tuple = time.localtime() print("当前时间 (struct_time):", local_time_tuple) # 或者使用特定时间戳 timestamp = time.time() converted_tuple = time.localtime(timestamp) print("时间戳转struct_time:", converted_tuple)
time.strftime(format[, t]) - 格式化本地时间。
import time # 获取当前时间并格式化为“年-月-日 时:分:秒” formatted_time = time.strftime('%Y-%m-%d %H:%M:%S') print("格式化当前时间:", formatted_time) # 使用特定时间戳 timestamp = time.time() custom_format = time.strftime("%Y%m%d_%H%M%S", time.localtime(timestamp)) print("格式化后的时间戳:", custom_format)
格式化符号:
-
%y 两位数的年份表示(00-99)
-
%Y 四位数的年份表示(000-9999)
-
%m 月份(01-12)
-
%d 月内中的一天(0-31)
-
%H 24小时制小时数(0-23)
-
%I 12小时制小时数(01-12)
-
%M 分钟数(00=59)
-
%S 秒(00-59)
-
%a 本地简化星期名称
-
%A 本地完整星期名称
-
%b 本地简化的月份名称
-
%B 本地完整的月份名称
-
%c 本地相应的日期表示和时间表示
-
%j 年内的一天(001-366)
-
%p 本地A.M.或P.M.的等价符
-
%U 一年中的星期数(00-53)星期天为星期的开始
-
%w 星期(0-6),星期天为星期的开始
-
%W 一年中的星期数(00-53)星期一为星期的开始
-
%x 本地相应的日期表示
-
%X 本地相应的时间表示
-
%Z 当前时区的名称
-
%% %号本身
属性(time模块本身没有属性,但可以通过其提供的函数生成的对象来访问属性)
对于struct_time对象(由time.localtime()或time.gmtime()等返回),它是一个元组,可以按索引访问各个时间元素:
属性 | 值 |
---|---|
tm_year | 年 |
tm_mon | 月:1 到 12 |
tm_mday | 日:1 到 31 |
tm_hour | 时:0 到 23 |
tm_min | 分:0 到 59 |
tm_sec | 秒:0 到 61 (60或61 是闰秒) |
tm_wday | 星期:0 到 6 (0是周一) |
tm_yday | 一年中的第几天,1 到 366 |
tm_isdst | 是否为夏令时,值有:1(夏令时)、0(不是夏令时)、-1(未知),默认 -1 |
import time local_time = time.localtime() # 访问struct_time的属性(索引) year = local_time.tm_year month = local_time.tm_mon day = local_time.tm_mday hour = local_time.tm_hour minute = local_time.tm_min second = local_time.tm_sec print(f"当前日期和时间:{year}-{month}-{day} {hour}:{minute}:{second}")
Python网络
Python requests 是一个常用的 HTTP 请求库,可以方便地向网站发送 HTTP 请求,并获取响应结果。
使用 requests 发送 HTTP 请求需要先下载并导入 requests 模块:
import requests
# 导入 requests 包 import requests response = requests.get('https://www.baidu.com')# 发送请求 print(response.content) # 获取响应内容 response2 = requests.get('http://localhost:7001/test')# 发送请求 print(response2.json()) # 获取json数据并解析
每次调用 requests 请求之后,会返回一个 response 对象,该对象包含了具体的响应信息,如状态码、响应头、响应内容等:
response的属性或方法 | 说明 |
---|---|
apparent_encoding | 编码方式 |
close() | 关闭与服务器的连接 |
content | 返回响应的内容,以字节为单位 |
cookies | 返回一个 CookieJar 对象,包含了从服务器发回的 cookie |
elapsed | 返回一个 timedelta 对象,包含了从发送请求到响应到达之间经过的时间量,可以用于测试响应速度。比如 r.elapsed.microseconds 表示响应到达需要多少微秒。 |
encoding | 解码 r.text 的编码方式 |
headers | 返回响应头,字典格式 |
history | 返回包含请求历史的响应对象列表(url) |
is_permanent_redirect | 如果响应是永久重定向的 url,则返回 True,否则返回 False |
is_redirect | 如果响应被重定向,则返回 True,否则返回 False |
iter_content() | 迭代响应 |
iter_lines() | 迭代响应的行 |
json() | 返回结果的 JSON 对象 (结果需要以 JSON 格式编写的,否则会引发错误) |
links | 返回响应的解析头链接 |
next | 返回重定向链中下一个请求的 PreparedRequest 对象 |
ok | 检查 "status_code" 的值,如果小于400,则返回 True,如果不小于 400,则返回 False |
raise_for_status() | 如果发生错误,方法返回一个 HTTPError 对象 |
reason | 响应状态的描述,比如 "Not Found" 或 "OK" |
request | 返回请求此响应的请求对象 |
status_code | 返回 http 的状态码,比如 404 和 200(200 是 OK,404 是 Not Found) |
text | 返回响应的内容,unicode 类型数据 |
url | 返回响应的 URL |
requests的方法
方法 | 描述 |
---|---|
delete(url, args) | 发送 DELETE 请求到指定 url |
get(url, params, args) | 发送 GET 请求到指定 url |
head(url, args) | 发送 HEAD 请求到指定 url |
patch(url, data, args) | 发送 PATCH 请求到指定 url |
post(url, data, json, args) | 发送 POST 请求到指定 url |
put(url, data, args) | 发送 PUT 请求到指定 url |
request(method, url, args) | 向指定的 url 发送指定的请求方法 |
requests.get(url, params ={key: value}, args)
-
url 请求 url。
-
params 参数为要发送到指定 url 的 JSON 对象。
-
args 为其他参数,比如 cookies、headers、verify等。
import requests # 图片URL地址 image_url = 'http://localhost:7001/public/1.png' # 发送GET请求获取图片数据 response = requests.get(image_url) # 检查请求是否成功(HTTP状态码为200) if response.status_code == 200:# 将图片数据写入本地文件with open('image.jpg', 'wb') as f:f.write(response.content)print("图片已成功下载并保存为 image.jpg") else:print(f"无法下载图片,响应状态码:{response.status_code}")
requests.post(url, data={key: value}, json={key: value}, args)
-
url 请求 url。
-
data 参数为要发送到指定 url 的字典、元组列表、字节或文件对象。
-
json 参数为要发送到指定 url 的 JSON 对象。
-
args 为其他参数,比如 cookies、headers、verify等。
import requests headers = {'User-Agent': 'Mozilla/5.0'} # 设置请求头 params = {'key1': 'value1', 'key2': 'value2'} # 设置查询参数 data = {'username': 'jack', 'password': '123456'} # 设置请求体 response = requests.post('http://localhost:7001/test', headers=headers, params=params, data=data) print(response.text)