1. Python 库

1.1 Import 原理

  1. 搜索路径:当执行 import 语句时,Python 会在一系列预定义的路径中搜索要导入的模块,搜索路径主要按照「内置模块 -> 当前目录 -> 环境变量 -> 标准库目录 -> .pth 文件 -> 第三方库路径」进行搜索。另外也可以通过 sys.path 得方式可以查看和修改的其他路径。
    • 内置模块:Python 解释器自带的模块,例如 math、os 等。
    • 当前目录:首先会在当前执行脚本所在的目录或所属项目目录中查找模块。
    • 环境变量:如果在当前目录中没有找到模块,会继续在 PYTHONPATH 环境变量中指定的目录列表中搜索。
    • 标准库路径:Python 安装目录下的标准库模块所在的路径。
    • .pth 文件:如果模块仍未找到,Python 会查看安装目录下的 .pth 文件,这些文件包含了额外的搜索路径。.pth 文件的作用和环境变量 PYTHONPATH 一样,都会把路径加到 sys.path。.pth 文件要放在 python 安装目录下的 lib\site-package 文件夹下,一行就代表一个路径。
    • 第三方库路径:如果通过 pip 安装了第三方库,通常在 Python 安装目录的 lib\site-packages 目录下。

Tips:

import 的搜索路径有两大步骤:先判断 import 后面的 XXX 包是不是内置模块,内置模块可以直接 import,基本不会报错。如果 XXX 不是内置的,那么就从 sys.path 的列表中依次查找 XXX(注意是依次,即有先后顺序),如果遍历完 sys.path 还找不到 XXX 就抛 ModuleNotFoundError 异常结束。

  1. 模块查找:Python 会按照指定的名称在搜索路径中查找对应的 .py 文件(对于 Python 模块)或包含 init.py 文件的目录(对于 Python 包)。
  2. 编译和缓存:如果找到模块并且是 .py 文件,Python 会将其编译为字节码(.pyc 或 .pyo 文件)以提高后续导入的性能。编译后的字节码会被缓存,下次导入时如果模块没有修改,将直接使用缓存的字节码。
  3. 执行模块代码:在导入模块时,模块中的顶层代码(不在函数或类内部的代码)会被执行,包括变量的定义、函数的定义等。
  4. 命名空间:导入的模块会在当前的命名空间中创建一个对应的名称,通过这个名称可以访问模块中的内容。

1.2 模块与包

1.2.1 定义

  • 模块: 在 Python 中,一个 .py 文件就是一个模块,模块让你能够有逻辑地组织你的 Python 代码段。模块能定义函数、类和变量等。
  • 包(目录): Python 包是一个分层次的文件目录结构,它定义了一个由模块及子包组成的 Python 的应用环境。简单来说,包就是文件夹,但该文件夹下必须存在 init.py 文件,该文件的内容可以为空,init.py 用于标识当前文件夹是一个包。

1.2.2 导入规范

导入一个模块就起一行,最好不要将多个模块导入放在同一行。另外,import 建议要放在文件头部,一般是放在 docstring 之后,全局变量或正式逻辑代码之前。

1
2
3
4
5
6
7
# 推荐每一个模块放一行
import os
import sys
import time

# 不推荐放在一行导入
import os, sys, time

尽量按照内置模块、第三方模块和本地模块的顺序导入。

1
2
3
4
5
6
7
8
9
10
11
# 内置模块
import os
import time

# 第三方模块
import request
import django
import flask

# 本地模块
import xxx

1.2.3 导入操作

导入整个模块

加入已经有写好的程序 pizza.py,那么可以通过 import 来调动这个程序,然后通过 import 的模块来调用其中的函数名进行使用:

1
2
3
import module_name

module_name.function_name( )

例如:

1
2
3
import pizza

make_pizza(16, 'mushrooms')
导入特定函数(推荐用法)

可以导入模块中的特定函数,导入后想调用这些函数就不用加上前面的模块名了:

1
2
3
4
from module_name import function_name
from module_name import function_0, function_1, function_2

function_name()

例如:

1
2
3
from pizza import make_pizza

make_pizza(16, 'mushrooms')
导入模块中的所有函数(不推荐)

通过星号可以将模块中的所有函数都复制到这个程序文件中:

1
2
3
from module_name import *

function_name()

例如:

1
2
from pizza import *
make_pizza(16,'pepperoni')

这种方法使用需谨慎,如果模块中有函数的名称与当前项目中使用的名称相同,Python 会覆盖函数。

比如当前项目中有一个叫 func 的函数,然后从某个模块中又通过 “from module_name import *“ 导入了一个也叫 func 的函数。那么此时在当前项目中使用 func 时,实际上使用的是从模块中导入的那个 func 函数,而不是原本自己定义的那个。

但是在 my_package/__init__.py 文件中,可以定义 all 列表来指定当用户执行 from modname import * 时应该导入哪些模块或对象。

例如有如下包结构:

1
2
3
4
5
my_package/
__init__.py
module1.py
module2.py
module3.py

并且在 __all__ 这样设置:

1
__all__ = ['module1', 'module2']

如果 module1.py 中有一个函数 func1,module2.py 中有一个类 MyClass,现在当用户执行 from my_package import * 时,只会导入 module1 和 module2 这两个模块名.

使用 as
  • 给函数指定别名
1
2
from pizza import make_pizza as mp
mp(16,'pepperoni')
  • 给模块指定别名
1
2
import pizza as p
p.make_pizza(16,'pepperoni')

Tips:
导入类的方法和导入函数的方法是一致的,只是类名需要需要大写,因此下面就不再过多赘述了

导入类

已知文件 car.py,从此文件中向另一个文件导入 Car 类:

1
from car import Car

1.3 动态加载

动态加载模块,不需要提前导入相关模块,它可以根据运行条件来选择加载不同的模块,从而增强程序的灵活性和扩展性。

方法一: Python 提供了一个 importlib 模块,可以用于实现动态加载。

1
2
3
4
5
6
7
8
9
import importlib

def test_func():
module_name = 'math'
math = importlib.import_module(module_name)
result = math.sqrt(16)
print(result) # 4.0

test_func()

可以需要选择时机加载模块,按需加载,按需使用,延时加载模块。

另外,importlib 还有一些扩展的用法,但不是必须掌握的,一般用上面那种方法就足够了。对于这个扩展的用法,还是来看一个例子,在下面这个例子中:

  • 首先使用 spec_from_file_location 函数创建一个模块规格,指定了模块的名称和文件路径。
  • 然后,使用 module_from_spec 创建一个模块对象。
  • 接着通过 spec.loader.exec_module(module) 执行模块的代码,将模块加载到内存中。
  • 最后,可以使用导入的模块中的函数或属性。

方法二: 使用 __import__ 来实现动态加载。

1
2
3
4
5
6
os = __import__('os')

if platform.uname().system == 'Windows':
module = __import__('os')
else:
module = __import__('sys')

1.4 Pip 工具

1.4.1 官方下载源

Python 包官网地址:https://pypi.org/

Python 语言提供超过 15 万个第三方库,使用 pip 安装。

1.4.2 国内下载源

官网的包下载速度可能比较慢,因此也可以使用国内的下载源来下载第三方包:

如果要使用国内镜像源配置(以使用国内知名的 Python 镜像源 “ 阿里云 “ 为例),主要有两种方式使用方法:

  1. 可以在使用 pip 命令安装包时,通过 -i 参数指定镜像源,例如:
1
pip install 包名 -i https://mirrors.aliyun.com/pypi/simple/
  1. 永久配置(以配置阿里云镜像源为例):
  • Windows 系统:在用户目录下创建一个名为 pip 的文件夹,在该文件夹内创建一个名为 pip.ini 的文件,在文件中添加以下内容。
1
2
[global]
index-url = https://mirrors.aliyun.com/pypi/simple/
  • Linux 或 macOS 系统:在用户目录下创建一个 .pip 文件夹,在该文件夹内创建一个 pip.conf 文件,添加类似上述的内容。

另外,如果想将整个包都下载下来,则可以使用如下命令:

1
pip download 包名

2. 常用标准库

官方文档:https://docs.python.org/zh-cn/3.7/library/os.html

利用 Python 标准库或三方库,覆盖的功能场景包括:Web 框架、网络编程、网络爬虫、网络内容提取、模板引擎、数据库、数据可视化、图片处理、文本处理、自然语言处理、机器学习、日志、代码分析等。

Tips:

不用通过 pip 工具下载的库称为标准库,需要用 pip 工具下载的库称为第三方库。

有些问题可以通过现成的库进行解决,通过上面提供的链接可以寻找符合需求的库进行下载使用。

2.1 os 模块

2.1.1 Os 定义

os 模块是 Python 标准库中的一个用于访问操作系统相关功能的模块,使用 os 模块中提供的接口,可以实现跨平台访问。

os 模块的主要功能:系统相关、目录及文件操作、执行命令和管理进程

模块导入方式:

1
import os

2.1.2 使用方法

常见函数及方法

os 模块中包含了一系列文件操作相关的函数:

函数 功能
os.getcwd() 获取当前工作目录,即当前 python 脚本工作的目录路径
os.chdir(“..”) 改变当前脚本工作目录,相当于在 shell 下 cd
os.listdir(‘.’) 列出指定目录下的所有文件和子目录,包括隐藏文件
os.makedirs(‘dir1/dir2’) 可生成多层递归目录
os.removedirs(‘dirname’) 递归删除空目录
os.mkdir(‘dirname’) 生成单级目录
os.rmdir(‘dirname’) 删除单级空目录,若目录不为空则无法删除并报错
os.remove(‘filename’) 删除一个文件
os.rename(“oldname”,”newname”) 重命名文件 / 目录

os.path 模块不仅提供了一些操作路径字符串的方法,还包含一些或者指定文件属性的一些方法:

方法 功能
os.path.abspath(path) 返回 path 的绝对路径。
os.path.basename(path) 获取 path 路径的基本名称,即 path 末尾到最后一个斜杠的位置之间的字符串。
os.path.dirname(path) 返回 path 路径中的目录部分。
os.path.exists(path) 判断 path 对应的文件是否存在,如果存在,返回 True;反之,返回 False。
os.path.getatime(path) 返回 path 所指文件的最近访问时间 (浮点型秒数)。
os.path.getmtime(path) 返回文件的最近修改时间(单位为秒)。
os.path.getctime(path) 返回文件的创建时间(单位为秒,自 1970 年 1 月 1 日起(又称 Unix 时间))
os.path.getsize(path) 返回文件大小,如果文件不存在就返回错误。
os.path.isabs(path) 判断是否为绝对路径。
os.path.isfile(path) 判断路径是否为文件。
os.path.isdir(path) 判断路径是否为目录。
os.path.join(path1[, path2[, …]]) 把目录和文件名合成一个路径。
os.path.realpath(path) 返回 path 的真实路径。
os.path.split(path) 把路径分割成 dirname 和 basename,返回一个元组。
os.path.splitdrive(path) 一般用在 windows 下,返回驱动器名和路径组成的元组。
os.path.splitext(path) 分割路径,返回路径名和文件扩展名的元组。
os.path.walk(path) 遍历 path,并会生成一个三元组 (dirpath, dirnames, filenames) ,对于目录树中的每个目录:

上面红色标注的方法是日常过程中比较常用的方法,其中前三个标红的方法使用方法如下。

1
2
3
4
5
6
7
8
import os

# 获取当前文件的绝对路径
print(os.path.abspath(__file__)) # /Users/Desktop/project/test_python/test.py
# 获取当前文件名
print(os.path.basename(__file__)) # test.py
# 获取当前文件所在目录
print(os.path.dirname(__file__)) # /Users/Desktop/project/test_python

而 listdr 和 walk 方法都可用于遍历目录,其使用场景如下:

  • 场景 1:在一个目录中只有文件,没有子文件夹,使用 os.listdir
  • 场景 2:一个目录下既有子目录也有文件,需要递归遍历时,使用 os.walk

walk 函数声明:

  • 返回值:函数返回一个元组,含有三个元素。
  • 分别是:每次遍历的路径名、路径下子目录列表、目录下文件列表。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import os

path = "."

# 在一个目录下只有文件,没有文件夹,这个时候可以使用 os.listdir 遍历
for filename in os.listdir(path):
print(os.path.join(path, filename))

# 递归的情况,一个目录下既有目录也有文件,则可以使用 os.walk 遍历
for root, dirs, files in os.walk(path):
# 继续遍历当前目录下的所有文件
for name in files:
print(os.path.join(root, name))
# 继续遍历当前目录下的所有目录
for name in dirs:
print(os.path.join(root, name))

执行命令

使用 os 模块中的 system 或者 popen 等方法可以执行操作系统的命令令。

  1. os.system(command)

运行操作系统命令,直接显示结果。但返回值是 0 或 -1,不能获得显示在屏幕上的数据。其中 command 是要执行的命令字符串。

1
2
3
import os

os.system("ls")

  1. os.popen(command, [mode, [bufsize]])

如果想将执行的命令结果持久化到变量中,则可以使用这个方法。它开启了一个子进程执行 command 参数指定的命令,在父进程和子进程之间建立一个管道 pipe,用于在父子进程间通信,并通过 read() 方法将命令的结果返回。

1
2
3
4
5
import os

ret = os.popen("ls")
print(ret)
print(ret.read())

2.2 Sys 模块

2.2.1 Sys 定义

sys 模块主要是针对与 Python 解释器相关的变量和方法,不是主机操作系统。

导入方式:

1
import sys

2.2.2 使用方法

方法/属性 功能
sys.argv 获取命令行参数列表,第一个元素是程序本身
sys.exit(n) 退出 Python 程序,exit(0) 表示正常退出。当参数非 0 时,会引发一个 SystemExit 异常,可以在程序中捕获该异常
sys.version 获取 Python 解释程器的版本信息
sys.path 返回模块的搜索路径,初始化时使用 PYTHONPATH 环境变量的值
sys.platform 返回操作系统平台名称
sys.exc_info() 返回异常信息三元元组
sys.getdefaultencoding() 获取系统当前编码,默认为 utf-8
sys.setdefaultencoding() 设置系统的默认编码
sys.getfilesystemencoding() 获取文件系统使用编码方式,默认是 utf-8
sys.modules 以字典的形式返回所有当前 Python 环境中已经导入的模块
sys.copyright 当前 Python 的版权信息
sys.getrefcount(object) 返回对象的引用数量
sys.getrecursionlimit() 返回 Python 最大递归深度,默认为 1000
sys.getsizeof(object[, default]) 返回对象的大小
sys.getwindowsversion() 返回当前 windwos 系统的版本信息
  1. sys.argv

sys.argv 是一个脚本执行参数列表,列表的第一个元素是脚本名称,从第二个元素开始才是真正的参数。

1
2
3
4
5
import sys

# 打印参数列表
for index, arg in enumerate(sys.argv):
print("第 %d 个参数是:%s" % (index, arg))

  1. sys.path

sys.path 是 Python 的搜索模块的路径集合,Python 就会按照这个路径集合搜索查找模块。

1
2
3
4
5
import sys

# 模块搜索路径
for path in sys.path:
print(path)

如果想添加模块查找的路径,则可以直接使用 append 方法添加。

1
sys.path.append("C:\\")    # 将 C 盘路径添加到模块的查找的路径中

2.3 Time 模块

2.3.1 Time 定义

time 模块是 python 专门用来处理时间的内建库。

导入方式:

1
import time

2.3.2 使用方法

时间获取

在 Python 中,通常有这几种方式来表示时间:

  • 时间戳
  • 时间字符串
  • 时间元组(struct_time)
1
2
3
4
5
6
7
8
9
10
11
12
13
import time

# 获取时间戳
t1 = time.time()
print(int(t1)) # 1723771496

# 获取时间元组
t2 = time.localtime()
print(t2) # time.struct_time(tm_year=2024, tm_mon=8, tm_mday=16, tm_hour=9, tm_min=24, tm_sec=56, tm_wday=4, tm_yday=229, tm_isdst=0)

# 获取时间字符串
t3 = time.asctime()
print(t3) # Fri Aug 16 09:24:56 2024

时间类型转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import time

# 获取时间戳
t1 = time.time()
print(int(t1)) # 1723772044

# 将一个时间戳转换为时间元组
t2 = time.localtime((t1))
print(t2) # time.struct_time(tm_year=2024, tm_mon=8, tm_mday=16, tm_hour=9, tm_min=34, tm_sec=4, tm_wday=4, tm_yday=229, tm_isdst=0)

# 再将时间元组转换回时间戳
t3 = time.mktime(t2)
print(t3) # 1723772044.0

# 将时间戳转换成时间字符串
t4 = time.ctime(t3)
print(t4) # Fri Aug 16 09:34:04 2024

时间类型格式化

  1. time.strftime(format[, struct_time])

传入格式和 struct_time,返回按照 format 格式化后的时间字符串。

1
2
3
4
5
6
7
8
9
10
11
import time

# 将 struct_time 对象转换成格式化时间字符串
t1 = time.strftime("%Y-%m-%d %H:%M:%S")
print(t1) # 2024-08-16 09:37:36

t = time.localtime() # 在睡眠前获取
time.sleep(3)

t2 = time.strftime("%Y-%m-%d %H:%M:%S", t)
print(t2) # 2024-08-16 09:37:36
  1. time.strptime(string[, format])

将字符串时间转为 struct_time,time.strftime() 的逆向操作。

1
2
3
4
5
6
import time

# 将时间字符串转换成 struct_time 对象
time_str = "2010-01-01 20:00:00"
t = time.strptime(time_str, "%Y-%m-%d %H:%M:%S")
print(t) # time.struct_time(tm_year=2010, tm_mon=1, tm_mday=1, tm_hour=20, tm_min=0, tm_sec=0, tm_wday=4, tm_yday=1, tm_isdst=-1)

2.4 Itertools 模块

2.4.1 Itertools 定义

官方文档:https://docs.python.org/zh-cn/3.7/library/itertools.html

编程中会用到很多需要迭代的地方,强大的 Python 已经为我们提供了 itertools 内置库,用来帮助开发人员更便捷的编码。

导入方式:

1
import itertools

2.4.2 使用方法

  • 迭代计数 - itertools.count()
1
2
3
4
5
6
7
8
9
import itertools

# 计数:从 1 开始,按照步长为 2 的间距迭代至 100 为止
c = itertools.count(start=1, step=2)
for i in c:
if i> 10:
break
else:
print(i)

  • 循环迭代 - itertools.cycle()
1
2
3
4
5
6
7
8
9
10
import itertools

# itertools.cycle 传入一个可迭代对象,然后无限循环迭代
list1 = [1, 2, 3]
num = 0
for i in itertools.cycle(list1):
print(i)
num = num + 1
if num == 7:
break

  • 重复迭代 - itertools.repeat()
1
2
3
4
5
import itertools

# itertools.repeat 重复迭代一个可迭代对象,如果不指定 times,则会迭代无数次,也可以通过 times 参数指定迭代的次数
for i in itertools.repeat('hello world', 5):
print(i)

  • 拼接迭代器 - itertools.chain()
1
2
3
4
5
6
7
import itertools

# itertools.chain 连接多个列表或者迭代器,把传入的多个 iterable 拼接一个迭代器,并且按传入顺迭代
list1 = [1, 2, 3]
list2 = ('a', 'b', 'c')
for i in itertools.chain(list1, list2):
print(i)

  • 排列组合 - itertools.permutations()
1
2
3
4
import itertools

l1 = list(itertools.permutations([1, 2, 3]))
print(l1)

  • 指定元素组合 - itertools.combinations()
1
2
3
4
5
6
7
8
9
10
import itertools

# itertools.combinations 元素组合
list1 = [1, 2, 3, 4, 5]
x = itertools.combinations(list1, 2)
print(list(x))

# itertools.combinations_with_replacement 允许重复元素组合
x = itertools.combinations_with_replacement(list1, 2)
print(list(x))

  • 求笛卡尔积 - itertools.product()
1
2
3
4
5
6
7
import itertools

# itertools.product 用于求多个可迭代对象的笛卡尔积(Cartesian Product)
A = [1, 2, 3]
B = [100, 200, 300]
for item in itertools.product(A, B):
print(item)

Tips:笛卡尔积、元素组合以及排列组合之间的区别

  1. 笛卡尔积:
    • 笛卡尔积是两个或多个集合中元素的所有可能有序对的集合。
    • 它强调的是不同集合之间元素的配对,并且顺序是重要的。
    • 例如,集合 A = {1, 2} 和集合 B = {a, b} 的笛卡尔积是 {(1, a), (1, b), (2, a), (2, b)}。
  2. 元素组合:
    • 组合是从给定的集合中选取一定数量的元素形成子集,不考虑元素的顺序。
    • 例如,从集合 {1, 2, 3} 中选取 2 个元素的组合有 {1, 2} 、{1, 3} 、{2, 3}。
  3. 排列组合:
    • 排列是从给定的集合中选取一定数量的元素进行排列,元素的顺序是重要的。
    • 例如,从集合 {1, 2, 3} 中选取 2 个元素的排列有 12、21、13、31、23、32。

总结来说,笛卡尔积是不同集合元素的配对;组合只关注选取的元素集合,不考虑顺序;排列则既关注选取的元素集合,又考虑元素的顺序。

2.5 Collections 模块

2.5.1 Collections 定义

官方文档:https://docs.python.org/zh-cn/3.7/library/collections.html

Collections 模块 – Python 标准库,是数据结构常用模块。

导入方式:

1
import collections

2.5.2 使用方法

计数功能

1
2
3
4
5
6
7
8
9
10
11
12
13
from collections import *

# Counter 计数功能
list1 = ["a", "b", "c", "c", "a", "a"]
count = Counter(list1)
print(count) # Counter({'a': 3, 'c': 2, 'b': 1})
print(count.keys()) # dict_keys(['a', 'b', 'c'])
print(count.values()) # dict_values([3, 1, 2])
print(count['a']) # 3

# most_common,返回一个列表,包含 counter 中 n 个最大数目的元素
print(Counter("aabbcaedds").most_common()) # [('a', 3), ('b', 2), ('d', 2), ('c', 1), ('e', 1), ('s', 1)]
print(Counter("aabbcaedds").most_common(2)) # [('a', 3), ('b', 2)]

队列模拟

Deque 模块是 Python 标准库 collections 中的一项,它提供了两端都可以操作的序列,这意味着你可以在序列前后都执行添加或删除,并且可以限制队列容量。

常规操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import collections

# 创建双向队列
d = collections.deque()

# deque 提供了类似 list 的操作方法
# 往右添加元素
d.append(1)
d.append(2)
print(d) # deque([1, 2])

# 往左添加元素
d.appendleft(5)
print(d) # deque([5, 1, 2])

# 在指定位置添加元素
d.insert(1, 'a')
print(d) # deque([5, 'a', 1, 2])

# 获取最右边一个元素,并在队列中删除
x = d.pop()
print(x, d) # 2 deque([5, 'a', 1])

限制队列最大长度:

1
2
3
4
5
6
7
8
9
10
import collections

# 还可以显示 deque 的长度,当限制长度的 deque 增加超过限制数的项时,另一边的项会自动删除
d = collections.deque(maxlen=3)
d.append(1)
d.append(2)
d.append(3)
print(d) # deque([1, 2, 3], maxlen=3)
d.append(4)
print(d) # deque([2, 3, 4], maxlen=3)

2.6 Inspect 模块

2.6.1 Inspect 定义

官方文档:https://docs.python.org/zh-cn/3.7/library/inspect.html

inspect 模块用于收集 python 对象的信息,可以获取类或函数的参数的信息和源码、解析堆栈、对对象进行类型检查等。

导入方式:

1
import insepct

inspect 模块主要提供了四种用处:

  • 对是否是模块、框架、函数进行类型检查
  • 获取源码
  • 获取类或者函数的参数信息
  • 解析堆栈

2.6.2 使用方法

获取源码

1
2
3
4
5
6
7
8
9
10
import inspect
from unittest import TestCase

# 获取源码
def add(x, y):
print('add function')
return x + y

print(inspect.getsource(add))
print(inspect.getsource(TestCase))

获取函数路径及文档字符串

1
2
3
4
5
6
7
8
9
import inspect

def add(x, y):
"这是一个 add 函数"
print('add function')
return x + y

print(inspect.getsourcefile(add)) # /Users/Desktop/project/test_python/test/test.py
print(inspect.getdoc(add)) # 这是一个 add 函数

获取模块的所有类

1
2
3
4
5
6
7
8
9
10
11
12
import inspect
import unittest

# 获取该模块的所有类
for name, obj in inspect.getmembers(unittest):
"""获取该模块的所有类"""
if inspect.ismodule(obj):
print('是否是一个模块:' + obj.__name__)
if inspect.isclass(obj):
print('是否是一个类:'+obj.__name__)
if inspect.ismethod(obj):
print('是否是一个方法:'+obj.__name__)

2.7 Csv 模块

2.7.1 Csv 定义

csv 模块是用于处理逗号分隔值(Comma-Separated Values,CSV)文件的工具模块,使用场景如下:

  1. 数据导入和导出:当需要从外部数据源(如电子表格、数据库导出等)读取数据或将数据导出到其他应用程序时,CSV 格式通常是一种简单且广泛支持的格式。csv 模块可以方便地读取和写入这些 CSV 文件,以便在 Python 程序中进行进一步的处理。
  2. 数据处理和分析:如果需要对大量的数据进行处理和分析,而这些数据以 CSV 格式存储,csv 模块可以帮助快速读取数据,并进行各种操作,如筛选、转换、聚合等。可以使用 reader 和 writer 对象结合其他 Python 数据处理库来实现复杂的数据处理流程。
  3. 与其他工具和系统集成:许多其他软件工具和系统支持 CSV 格式作为输入或输出。通过使用 csv 模块,Python 程序可以与这些工具进行交互,读取它们生成的 CSV 文件或生成 CSV 文件供它们使用。例如,可以将 Python 程序生成的数据导出为 CSV 文件,以便在电子表格软件中进行进一步的分析和可视化。

导入方式:

1
import csv

另外,csv 和 excel 比较相似,但 csv 是纯文本格式,且结构简单仅存储数据,无格式和公式等,易被编程处理;而 excel 文件格式丰富,可含多个工作表及格式、公式、图表等,功能强大但相对复杂。

2.7.2 使用方法

写入文件

1
2
3
4
5
6
7
8
9
10
11
12
13
import csv

header = ['姓名', '年纪', '国家']
data = [
['张三', 18, '中国'],
['李四', 19, '小日本'],
['王五', 20, '美国']
]

with open("data.csv", "w") as file:
write = csv.writer(file)
write.writerow(header)
write.writerows(data)

执行上述代码后,会在本地创建一个 ‘data.csv’ 文件,并往里面写入数据。

读取文件

1
2
3
4
5
6
7
8
9
10
11
12
13
import csv

header = ['姓名', '年纪', '国家']
data = [
['张三', 18, '中国'],
['李四', 19, '小日本'],
['王五', 20, '美国']
]

with open("data.csv", "r") as file:
reader = csv.reader(file)
for row in reader:
print(row)

3. 工作常用第三方库

3.1 命令行工具

3.1.1 常见工具

常见命令行工具:

  • argparse 是 Python 标准库中的一个模块,它提供了丰富的功能来定义命令行参数的名称、类型、默认值、帮助信息等。通过它,您可以轻松地处理用户在命令行中输入的各种参数,并且可以进行参数的验证和错误处理。
  • click 这个库具有高度的灵活性和可扩展性。它支持命令的嵌套、参数的多种类型(包括文件、目录等)、选项的别名、参数的自动文档生成等。使用 click 可以让命令行工具的定义更加清晰和易读。
  • fire 则以一种非常简洁的方式将现有的 Python 函数或对象转换为命令行接口。您不需要显式地定义参数和选项,fire 会根据函数的参数自动进行处理。

除了 Python 自带的命令行标准库外,click 库是最受欢迎、使用最多的第三方 Python 命令行解析工具。下面主要会介绍 click 库的使用,在此之前需要先安装一下这个第三方库。

1
pip install click

3.1.2 使用方法

方法及装饰器 作用
@click.command() 用于将函数标记为命令行命令。
@click.option() 定义命令行选项。可以指定选项名称、短选项(如 -n )、长选项(如 --name )、提示信息、默认值、是否必填等。
@click.argument() 定义命令行参数。可以指定参数名称、参数个数等。
click.echo() 用于在命令行中输出文本。
click.prompt() 用于在命令行中提示用户输入。
click.confirm() 用于向用户显示一个确认提示,并返回布尔值表示用户的选择。
click.group() 用于创建命令组,可以包含多个子命令。
click.Context 命令执行的上下文对象,可以获取命令行参数、选项的值,以及执行其他与上下文相关的操作。

示例一

  • 下面通过 @click.command() 将 print_msg 方法标记为了命令行命令。
  • 通过 @click.option 设置命令行传入参数 --name,以及默认值、提示信息和参数类型。
1
2
3
4
5
6
7
8
9
import click

@click.command()
@click.option("--name", default="hello", help="打印名称", type=str)
def print_msg(name):
click.echo(f"名称为:{name}")

if __name__ == '__main__':
print_msg()

示例二

  • 下面代码在上面示例的基础上,通过 @click.argument 装饰器指定了命令行必传的参数。
1
2
3
4
5
6
7
8
9
10
11
import click

@click.command()
@click.option("--count", default=1, help="打印次数", type=int)
@click.argument("name")
def print_msg(count, name):
for x in range(count):
click.echo(f"名称为:{name}")

if __name__ == '__main__':
print_msg()

我们也可以通过 --help 来查看一下提示信息,和上个示例不同,在 test.py [OPTIONS] 旁增加了一个必填的参数 NAME,除 NAME 外下面的 Options 选项里的都是选填参数。

3.2 定时工具

3.2.1 APScheduler 定义

这里我们会介绍一个简单易用的定时工具库 - APScheduler,在使用它之前同样需要安装一下。

1
pip install apscheduler

APScheduler 的一些关键特点和概念:

  1. 调度器(Scheduler)
    • BlockingScheduler:在执行任务时会阻塞当前线程,直到调度器被停止。
    • BackgroundScheduler:在后台运行,不会阻塞当前线程。
  2. 触发器(Trigger)
    • 决定任务何时执行。常见的触发器类型包括:
    • IntervalTrigger:按照固定的时间间隔执行任务。
    • DateTrigger:在指定的日期和时间执行一次任务。
    • CronTrigger:通过 cron 表达式来灵活定义任务的执行时间规则。
  3. 任务存储(Job Store)
    • 用于存储任务的信息,如任务的下次执行时间等。支持内存存储和数据库存储等方式。
  4. 执行器(Executor)
    • 负责执行任务。默认提供了线程池和进程池执行器。

3.2.2 使用方法

使用 APScheduler 的一般步骤:

  1. 创建调度器对象,如 BlockingScheduler 或 BackgroundScheduler。
  2. 定义任务函数。
  3. 使用适当的触发器创建任务,并将任务添加到调度器中。
  4. 启动调度器。

使用 DateTrigger

下面这个例子定义了一个打印的函数,并使用 date 作为触发器,在启动调度器之后,任务函数将会在指定的时间 2024.8.13 9:41:00 的时候执行打印操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import datetime
from apscheduler.schedulers.blocking import BlockingScheduler

# 创建调度器对象
scheduler = BlockingScheduler()

# 定义任务函数
def print_msg(text):
print(text)

# 使用 date 触发器创建任务,并添加到调度器中
scheduler.add_job(print_msg, 'date', run_date=datetime.datetime(2024, 8, 13, 9, 41, 00), args=['hello world'])

# 启动调度器
scheduler.start()

使用 IntervalTrigger

下面这个示例则是使用 interval 作为触发器,通过 seconds=5 定义了任务函数每 5 秒执行一次,并且也定义了 end_date,将任务函数执行的截止时间设置在 2024-8-13 12:00:00。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from apscheduler.schedulers.blocking import BlockingScheduler

# 创建调度器对象
scheduler = BlockingScheduler()

# 定义任务函数
def print_msg(text):
print(text)

# 使用 interval 触发器创建任务,并添加到调度器中
scheduler.add_job(print_msg, 'interval', seconds=5, args=['hello world'], end_date="2024-8-13 12:00:00")

# 启动调度器
scheduler.start()

使用 CronTrigger

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from apscheduler.schedulers.blocking import BlockingScheduler

# 创建调度器对象
scheduler = BlockingScheduler()

# 定义任务函数
def print_msg(text):
print(text)

# 使用 cron 触发器创建任务,并添加到调度器中
scheduler.add_job(print_msg, 'cron', second='*/5', args=['hello world'])

# 启动调度器
scheduler.start()

cron 触发器相对上面两个触发器则更加的灵活,不仅可以指定具体的执行日期,还可以指定执行的周期。下面这个例子,同样展示的是每 5 秒执行一次任务。

3.3 监控工具

3.3.1 Psutil 定义

官方文档:https://github.com/giampaolo/psutil

psutil 是一个跨平台的进程和系统监控的 Python 库,它提供了丰富的函数来获取系统的运行信息,例如 CPU、内存、磁盘、网络、进程等方面的信息。

psutil 的主要特点和功能:

  1. CPU 信息
    • 获取 CPU 的使用率,包括整体使用率和每个核心的使用率。
    • 获取 CPU 的时间统计,如用户时间、系统时间、空闲时间等。
  2. 内存信息
    • 查看系统的物理内存和交换内存的总量、使用量、空闲量等。
    • 获取内存的详细信息,如缓冲区、缓存等。
  3. 磁盘信息
    • 获得磁盘的分区信息、使用率、读写情况等。
    • 监控磁盘的 I/O 操作。
  4. 网络信息
    • 获取网络接口的地址、状态、流量统计等。
    • 查看网络连接的详细信息。
  5. 进程信息
    • 遍历系统中的进程,获取进程的 ID、名称、状态、内存使用、CPU 使用等。
    • 可以对进程进行操作,如终止进程。

其功能主要集中在系统监控、性能分析和对比以及进程管理这几个维度,它也可以让你实现类似任务管理器、top 命令的同等效果,也可以自定义让其满足你的特定需求。

当然在使用之前,同样需要先下载一下这个第三方库。

1
pip install psutil

3.3.2 使用方法

获取 CPU 使用率

1
2
3
4
5
6
import psutil

# 每 1 秒获取一次 CPU 使用率,一共获取 5 次
for i in range(5):
cpu_percent = psutil.cpu_percent(interval=1)
print(f'CPU使用率:{cpu_percent}')

获取内存信息

1
2
3
4
5
6
7
import psutil

mem_info = psutil.virtual_memory()
print(mem_info) # 获取内存对象
print(f"当前内存的占比:{mem_info.percent}%")
print(f"内存总量:{mem_info.total/(1024**3):.2f}GB")
print(f"内存占用:{mem_info.used/(1024**3):.2f}GB")

获取磁盘信息

1
2
3
4
5
6
7
import psutil

disk_info = psutil.disk_usage("/")
print(disk_info) # 获取磁盘对象
print(f"当前磁盘的占比:{disk_info.percent}%")
print(f"磁盘总量:{disk_info.total/(1024**3):.2f}GB")
print(f"磁盘已用:{disk_info.used/(1024**3):.2f}GB")

获取网络链接信息

net_connections 会返回一个包含连接信息的列表,每个元素都是一个表示连接的元组,元组中的信息通常包括以下内容:

  • fd:文件描述符
  • family:地址族(如 AF_INET 表示 IPv4,AF_INET6 表示 IPv6)
  • type:连接类型(如 SOCK_STREAM 表示 TCP,SOCK_DGRAM 表示 UDP)
  • laddr:本地地址(IP 和端口)
  • raddr:远程地址(IP 和端口)
  • status:连接状态(如 ESTABLISHED 表示已建立的连接)
  • pid:拥有该连接的进程 ID
1
2
3
import psutil

print(psutil.net_connections())

获取进程信息

1
2
3
4
5
6
import psutil

process = psutil.process_iter()

for proc in process:
print(f"进程名称:{proc.name},进程 ID 为:{proc.pid}")

3.4 造数工具

3.4.1 Faker 定义

官方文档:https://github.com/joke2k/faker

Faker 是一个 Python 包,开源的 GITHUB 项目,主要用来创建伪为数据,使用 Faker 包,无需再手动生成或者手写随机数来生成数据,只需要调用 Faker 提供的方法,即可完成数据的生成。

安装命令:

1
pip install faker

导入方式:

1
from faker import Faker

3.4.2 使用方法

1
2
3
4
5
6
7
8
9
10
11
12
from faker import Faker

faker = Faker('zh_CN')

print('name: ', faker.name())
print('address: ', faker.address())
print('phone: ', faker.phone_number())
print('ssn: ', faker.ssn())
print('url: ', faker.url())
print('image url: ', faker.image_url())
print('random str: ', faker.pystr())
print('text: ', faker.text())

3.5 其它工具

3.5.1 文字转语音

我们再介绍一个 pyttsx3 库,它可以将文本转换成语音。在使用之前,同样需要下载一下这个第三方库。

1
pip install pyttsx3

下面这段示例在运行的时候,系统就会读出 Hello World 这段话。

1
2
3
4
5
6
7
8
9
10
11
import pyttsx3

# 初始化引擎
engine = pyttsx3.init()

engine.setProperty('rate', 150) # 调整语速
engine.setProperty('volume', 0.9) # 调整音量

# 将文本转换为语音并播放
engine.say("Hello, World!")
engine.runAndWait()

3.5.2 进度条显示工具

tqdm 是一个 Python 库,用于在命令行或终端中为迭代过程提供一个进度条,让用户能够直观地了解任务的进展情况。,在使用之前也需要先下载这个第三方库。

1
pip install tqdm

示例一

1
2
3
4
5
6
import time
from tqdm import tqdm

# 对一个范围进行进度显示
for i in tqdm(range(100)):
time.sleep(0.1)

示例二

1
2
3
4
5
6
import time
from tqdm import tqdm

# 显示描述信息
for i in tqdm(range(100), desc="正在处理"):
time.sleep(0.1)

示例三

1
2
3
4
5
6
7
import time
from tqdm import tqdm

with tqdm(total=100) as pbar:
for i in range(10):
pbar.update(2)
time.sleep(0.1)

示例四

1
2
3
4
5
6
7
8
9
10
from tqdm import tqdm, trange
import time

pbar = trange(10)

# 分段打印
for i in pbar:
time.sleep(1)
if not (i % 3):
tqdm.write(f"进度{i}")