第四章 python的标准库
python中存在许多实用的标准库,在此之前我们就提到过
**collections**
和
heapq
,今天在本章我们将介绍其余非常实用的标准库。
一、 os
1.1 基本功能
os库是Python中与操作系统交互的一个非常重要的标准库。它提供了一系列函数,允许Python程序执行许多与操作系统相关的操作。os库的主要功能包括文件和目录操作、路径操作、环境变量管理、进程管理以及文件属性和权限操作等。
- 文件和目录操作:os库提供了一系列函数用于创建、删除、移动和重命名文件和目录。这些函数为Python程序提供了在文件系统中进行导航和修改的能力。
- 路径操作:os.path模块专门用于处理文件路径。这包括获取路径的特定部分(如目录名或文件名),判断路径是否存在,以及合并或拆分路径等。
- 环境变量:os库中的os.environ是一个包含当前环境变量的字典。通过它,Python程序可以获取、设置或修改环境变量的值。
- 进程管理:os库也提供了一系列函数用于进程管理。例如,可以使用os.system()函数执行系统命令,os.getpid()函数获取当前进程的ID,以及os.fork()函数创建子进程等。
- 文件属性和权限操作:os库还包含用于处理文件属性和权限的函数。例如,可以使用os.stat()函数获取文件的属性,如大小、创建时间等;使用os.chmod()函数修改文件的权限。
1.2 文件和目录操作
os
库提供了丰富的文件和目录操作函数,这些函数使得 Python 程序能够方便地创建、删除、修改文件和目录。以下是一些常用的文件和目录操作函数及其示例:
1.2.1 目录操作
os.mkdir(path)
: 创建新目录。
import os
os.mkdir('new_directory') # 创建一个名为 'new_directory' 的新目录
os.rmdir(path)
: 删除空目录。
os.rmdir('empty_directory') # 删除一个名为 'empty_directory' 的空目录
os.makedirs(path, exist_ok=False)
: 递归创建目录,类似于mkdir -p
。
os.makedirs('dir1/dir2/dir3') # 创建嵌套的目录结构
os.removedirs(path)
: 递归删除空目录。
os.removedirs('dir1/dir2/dir3') # 删除嵌套的空目录结构
os.chdir(path)
: 改变当前工作目录。
os.chdir('/path/to/directory') # 切换到指定目录
os.getcwd()
: 获取当前工作目录。
current_dir = os.getcwd() # 获取当前工作目录并存储在变量中
1.2.2 文件操作
os.remove(path)
或os.unlink(path)
: 删除文件。
os.remove('file.txt') # 删除名为 'file.txt' 的文件
os.rename(src, dst)
: 重命名文件或目录。
os.rename('old_name.txt', 'new_name.txt') # 重命名文件
1.3 路径操作
这些函数通常在 os.path
模块中提供:
os.path.exists(path)
: 检查路径是否存在。
if os.path.exists('file.txt'):
print("File exists.")
os.path.isfile(path)
: 检查路径是否是一个文件。
if os.path.isfile('file.txt'):
print("It's a file.")
os.path.isdir(path)
: 检查路径是否是一个目录。
if os.path.isdir('directory'):
print("It's a directory.")
os.path.join(path1, path2, ...)
: 连接一个或多个路径组件。
full_path = os.path.join('dir', 'subdir', 'file.txt')
print(full_path) # 输出:dir/subdir/file.txt (在 Windows 上可能是 dir\subdir\file.txt)
os.path.split(path)
: 将路径分割为目录和文件名两部分。
dir_name, file_name = os.path.split('/path/to/file.txt')
print(dir_name) # 输出:/path/to
print(file_name) # 输出:file.txt
os.path.basename(path)
: 返回路径中的文件名部分。
file_name = os.path.basename('/path/to/file.txt')
print(file_name) # 输出:file.txt
os.path.dirname(path)
: 返回路径中的目录部分。
dir_name = os.path.dirname('/path/to/file.txt')
print(dir_name) # 输出:/path/to
os.path.abspath(path)
: 返回指定文件的绝对路径。
abs_path = os.path.abspath('file.txt')
print(abs_path) # 输出文件的绝对路径
os.path.getsize(path)
: 返回指定文件的大小(以字节为单位)。
size = os.path.getsize('file.txt')
print(f"File size is {size} bytes.")
1.4 环境变量
在Python的os
库中,有几个函数用于处理环境变量,这些变量存储了操作系统级别的配置信息,比如路径、系统名称等。以下是一些常用的与环境变量相关的os
库函数以及它们的示例:
1.4.1 os.environ
os.environ
是一个映射对象,代表当前的环境变量。你可以通过它来获取、设置和删除环境变量。
示例:
-
获取环境变量
# 获取PATH环境变量的值 path_value = os.environ.get('PATH') print(path_value)
-
设置环境变量
# 设置一个新的环境变量MY_VAR os.environ['MY_VAR'] = 'my_value'
-
删除环境变量
# 删除环境变量MY_VAR if 'MY_VAR' in os.environ: del os.environ['MY_VAR']
1.4.2 os.pathsep
os.pathsep
是一个字符串,表示在环境变量值中用于分隔路径的分隔符。在Windows系统中,它通常是分号(;
),在Unix和类Unix系统中,它通常是冒号(:
)。
示例:
# 输出当前系统的路径分隔符
print(os.pathsep)
1.4.3 os.name
os.name
是一个字符串,指示正在使用的操作系统。它可以是'posix'
(对于Unix风格的操作系统,如Linux和Mac OS X),'nt'
(对于Windows),'os2'
,'ce'
,'java'
,'riscos'
等。
示例:
# 输出当前操作系统的名称
print(os.name)
1.4.4 os.system()
虽然os.system()
不是直接与环境变量相关的函数,但它用于执行shell命令,而shell命令可能会依赖于环境变量。这个函数返回命令的退出状态。
示例:
# 执行echo命令,输出PATH环境变量的值
status = os.system('echo $PATH') # 在Unix/Linux系统中
# 或者
status = os.system('echo %PATH%') # 在Windows系统中
请注意,直接使用os.system()
执行shell命令可能存在安全风险,特别是当命令字符串由不可信的输入构建时。在需要执行外部命令时,通常建议使用subprocess
模块,它提供了更强大且安全的功能。
1.4.5 os.putenv(key, value)
和 os.unsetenv(key)
这两个函数在某些操作系统上可用,用于设置和删除环境变量。不过,更推荐的做法是使用os.environ
映射对象,因为os.putenv()
和os.unsetenv()
的可用性可能会受到操作系统的限制。
示例:
-
设置环境变量 (如果可用)
os.putenv('MY_VAR', 'my_value')
-
删除环境变量 (如果可用)
os.unsetenv('MY_VAR')
请注意,不是所有的os
函数在所有操作系统上都可用,因此在实际编程中,最好先检查函数或属性是否存在,以避免运行时错误。你可以使用hasattr(os, 'function_name')
来检查特定的函数或属性是否存在于当前的os
模块中。
1.5 进程管理
在 Python 的 os
库中,直接关于进程管理的函数相对较少,因为进程管理通常涉及到更底层的操作系统功能,而在 Python 的标准库中,这些功能主要由 subprocess
模块来处理。然而,os
库确实提供了一些与进程相关的函数,如执行外部命令和获取当前进程 ID。
以下是一些与进程管理相关的 os
库函数和它们的示例:
1.5.1 os.getpid()
功能:获取当前进程的进程 ID。
示例:
import os
# 获取当前进程的进程 ID
current_pid = os.getpid()
print(f"当前进程的 PID: {current_pid}")
1.5.2 os.getppid()
功能:获取当前进程的父进程的进程 ID。
示例:
import os
# 获取当前进程的父进程的 PID
parent_pid = os.getppid()
print(f"当前进程的父进程的 PID: {parent_pid}")
1.5.3 os.fork()
功能:在 Unix/Linux 系统中创建一个新的进程,即当前进程的副本(称为子进程)。
注意:这个函数在 Windows 上不可用。
示例:
import os
# 创建子进程
pid = os.fork()
if pid == 0:
# 这是子进程执行的代码块
print(f"我是子进程,PID 是 {os.getpid()}")
else:
# 这是父进程执行的代码块
print(f"我是父进程,PID 是 {os.getpid()},创建了子进程 {pid}")
1.5.4 os.exec*()
系列函数
功能:在当前的进程空间中执行一个新的程序,替换当前进程的映像。这包括 os.execv()
, os.execve()
, os.execlp()
, os.execlpe()
, os.execvp()
, 和 os.execvpe()
等函数。
注意:调用 os.exec*()
函数后,当前进程的代码和数据会被新程序替换,因此通常不会在这些调用后继续执行任何代码。
示例(使用 os.execl()
):
import os
# 调用系统命令 ls 来列出当前目录的内容
# 注意:调用 exec 后,当前 Python 脚本的剩余部分将不会被执行
os.execl('/bin/ls', 'ls', '-l')
1.5.5 os.kill(pid, signal)
功能:向指定进程发送一个信号。在 Unix/Linux 系统中,这可以用来终止进程或执行其他操作。
注意:这个函数在 Windows 上可能不支持所有信号。
示例:
import os
import signal
# 假设我们有一个进程 PID
pid_to_kill = 1234
# 发送 SIGTERM 信号来尝试优雅地终止进程
os.kill(pid_to_kill, signal.SIGTERM)
1.5.6 os.waitpid(pid, options)
功能:等待指定进程结束,并返回其状态。这通常与 os.fork()
一起使用,以便父进程能够等待子进程完成。
示例:
import os
# 假设我们有一个子进程的 PID
child_pid = os.fork()
if child_pid == 0:
# 子进程代码...
exit(0)
else:
# 父进程代码...
_, status = os.waitpid(child_pid, 0)
print(f"子进程 {child_pid} 已结束,状态码是 {os.WEXITSTATUS(status)}")
1.5.7 os.spawn*()
系列函数
功能:在 Unix/Linux 系统上,这些函数用于创建新的进程来执行指定的程序,类似于 os.exec*()
,但 spawn
允许父进程继续执行。
注意:这些函数在 Windows 上不可用,且通常推荐使用 subprocess
模块来替代。
由于直接使用 os
库进行进程管理可能比较复杂且容易出错,所以在实际编程中,更推荐使用 subprocess
模块来执行外部命令和进行进程管理。subprocess
模块提供了更强大、更灵活且更安全的接口来与子进程交互。
1.6 文件属性和权限操作
在Python的os
库中,提供了多个函数用于获取和修改文件或目录的属性和权限。以下是其中一些重要的函数及其示例:
1.6.1 修改文件/目录权限
os.chmod(path, mode)
功能:更改文件或目录的权限。mode
是一个整数,表示Unix风格的权限。
示例:
import os
import stat
# 设置文件权限为只读
os.chmod('/path/to/file.txt', stat.S_IREAD)
1.6.2 获取文件/目录的访问和修改时间
os.path.getatime(path)
功能:返回指定路径的最后访问时间。
示例:
import os
import time
atime = os.path.getatime('/path/to/file.txt')
print(f"最后访问时间: {time.ctime(atime)}")
os.path.getmtime(path)
功能:返回指定路径的最后修改时间。
示例:
import os
import time
mtime = os.path.getmtime('/path/to/file.txt')
print(f"最后修改时间: {time.ctime(mtime)}")
1.6.3 检查文件/目录的访问权限
os.access(path, mode)
功能:检查当前用户是否有权限访问指定的路径。mode
可以是 os.F_OK
(检查存在性),os.R_OK
(检查可读性),os.W_OK
(检查可写性),或 os.X_OK
(检查可执行性)。
示例:
import os
# 检查文件是否存在
if os.access('/path/to/file.txt', os.F_OK):
print("文件存在")
# 检查文件是否可读
if os.access('/path/to/file.txt', os.R_OK):
print("文件可读")
1.6.5 链接操作
os.link(src, dst)
功能:在Unix系统上,创建一个硬链接。
示例:
import os
os.link('/path/to/source.txt', '/path/to/hardlink.txt')
os.symlink(src, dst)
功能:创建一个符号链接(也称为软链接)。
示例:
import os
os.symlink('/path/to/source.txt', '/path/to/symlink.txt')
注意
- 某些函数(如
os.chmod
和os.access
)在Windows上可能不可用或行为有所不同。 - 权限相关的函数通常只在Unix-like系统上有效,Windows的权限模型与Unix不同。
- 在修改文件或目录权限时,应小心操作,确保不会意外地限制了对重要文件或目录的访问。
使用这些函数时,应考虑到操作系统之间的差异,并遵循最佳的安全实践。此外,对于更复杂的文件操作,Python的shutil
模块也提供了许多有用的函数。
二、shutil
shutil
是Python标准库中的一个模块,主要用于文件和文件夹的高级操作,可以理解为Shell Utilities的简写。它封装了许多底层操作系统的功能,可以轻松地在Python中完成文件和文件夹的复制、移动、删除、压缩等常见操作。是对Python内置的os
模块的补充,使得文件和文件夹的操作更加便捷和高效。
shutil
模块的主要功能包括但不限于:
- 复制文件和文件夹:
shutil
提供了copy()
和copy2()
函数来复制文件,以及copytree()
函数来复制整个文件夹。这些函数能处理源文件和目标文件的各种情况,如源文件不存在、目标文件已存在等。 - 移动文件和文件夹:使用
move()
函数,你可以将文件或文件夹从一个位置移动到另一个位置。如果目标位置已经存在同名文件或文件夹,move()
函数会覆盖它。 - 删除文件和文件夹:
shutil
提供了rmtree()
函数来删除整个文件夹及其内容,以及os.unlink(path)
或os.remove(path)
来删除文件。
2.1 复制文件和文件夹
shutil
模块在Python中提供了强大的文件和文件夹复制功能。下面我将详细介绍shutil
中关于复制文件和文件夹的内容,并给出部分重要的示例。
复制文件
shutil.copy(src, dst)
这个函数将源文件src
复制到目标位置dst
。如果目标位置已存在同名文件,将会被覆盖。
示例:
import shutil
# 将source.txt复制到destination.txt
shutil.copy('source.txt', 'destination.txt')
shutil.copy2(src, dst)
这个函数类似于copy()
,但它也尝试复制源文件的元数据(如时间戳)。这对于保持文件的原始状态非常有用。
示例:
import shutil
# 将source.txt复制到destination_with_metadata.txt,并保留元数据
shutil.copy2('source.txt', 'destination_with_metadata.txt')
复制文件夹
shutil.copytree(src, dst)
这个函数递归地复制整个目录树。它会复制src
目录及其所有子目录和文件到dst
位置。如果dst
目录已存在,会引发异常。
示例:
import shutil
# 将source_directory复制到destination_directory
shutil.copytree('source_directory', 'destination_directory')
shutil.ignore_patterns(*patterns)
这是一个辅助函数,常与copytree()
一起使用,用于在复制目录时忽略与指定模式匹配的文件和目录。
示例:
import shutil
# 定义一个函数,使用ignore_patterns来忽略特定模式的文件
def copy_directory_ignoring_patterns(src, dst, patterns):
shutil.copytree(src, dst, ignore=shutil.ignore_patterns(*patterns))
# 复制source_directory到destination_directory,忽略所有.tmp结尾的文件和backup开头的目录
copy_directory_ignoring_patterns('source_directory', 'destination_directory', '*.tmp', 'backup*')
注意事项
- 在使用
shutil.copytree()
时,如果目标目录已存在,会引发FileExistsError
。如果需要覆盖已存在的目录,你需要先手动删除它,或者使用其他逻辑来处理这种情况。 - 在复制大量文件或大型文件夹时,请确保有足够的磁盘空间,并考虑复制操作的性能影响。
- 如果源文件或目标文件正在被其他进程使用,复制操作可能会失败。
2.2 移动文件和文件夹
shutil
模块在Python中提供了文件和文件夹的移动功能,使得在文件系统中移动文件或目录变得简单。下面我将详细介绍shutil
中关于移动文件和文件夹的内容,并给出部分重要的示例。
移动文件
在shutil
模块中,并没有直接提供一个名为“move”的函数来移动文件。但是,可以使用os.rename()
函数或者shutil.move()
函数来实现文件的移动。这两个函数都能将文件从一个位置重命名到另一个位置,从而达到移动的效果。
os.rename(src, dst)
这个函数可以将文件或目录从src
重命名为dst
,如果dst
是一个不同的路径,那么实际上就实现了文件的移动。
示例:
import os
# 将文件source.txt移动到新位置并重命名为new_source.txt
os.rename('source.txt', 'new_location/new_source.txt')
请注意,如果目标位置已经存在同名文件,os.rename()
会覆盖它。此外,如果源文件和目标文件在不同的文件系统中,os.rename()
可能会失败。
shutil.move(src, dst)
这个函数是shutil
模块提供的一个更健壮的文件移动方法。它首先尝试使用os.rename()
来移动文件或目录。如果os.rename()
失败(例如,因为源文件和目标文件在不同的文件系统中),shutil.move()
会回退到复制文件然后删除源文件的方式来实现移动。
示例:
import shutil
# 将文件source.txt移动到新位置并重命名为new_source.txt
shutil.move('source.txt', 'new_location/new_source.txt')
使用shutil.move()
的好处是它可以处理跨文件系统的移动操作,而不需要你编写额外的错误处理代码。
移动文件夹
对于文件夹的移动,同样可以使用os.rename()
或shutil.move()
。这两个函数都可以处理目录的移动。
示例:
import shutil
# 将目录source_directory移动到新位置并重命名为new_directory
shutil.move('source_directory', 'new_location/new_directory')
在这个例子中,shutil.move()
会将整个source_directory
目录及其所有内容移动到new_location
下,并重命名为new_directory
。
注意事项
- 在使用
os.rename()
或shutil.move()
移动文件或目录时,请确保源文件或目录存在,并且目标位置是可写的。 - 如果目标位置已经存在同名文件或目录,这些函数会覆盖它。在移动之前,请确保这是你想要的行为。
- 在移动大量文件或大型目录时,请考虑操作的性能影响,并确保有足够的磁盘空间。
通过使用os.rename()
或shutil.move()
,你可以轻松地在Python中移动文件和目录,满足各种场景下的需求。
2.3 删除文件和文件夹
shutil
模块在Python中提供了文件和文件夹的删除功能,允许我们方便地删除不需要的文件或整个目录结构。下面我将详细介绍shutil
中关于删除文件和文件夹的内容,并给出部分重要的示例。
删除文件
在shutil
模块中,并没有直接提供一个特定的函数来删除文件,但我们可以使用内置的os
模块中的os.remove()
函数来删除文件。
os.remove(path)
这个函数用于删除指定的文件。如果文件不存在,会引发FileNotFoundError
异常。
示例:
import os
# 删除文件source.txt
os.remove('source.txt')
删除文件夹
对于文件夹的删除,shutil
模块提供了shutil.rmtree()
函数,它可以递归地删除目录及其所有内容。
shutil.rmtree(path)
这个函数用于删除指定的目录及其所有子目录和文件。如果目录不存在,会引发FileNotFoundError
异常。
示例:
import shutil
# 删除目录source_directory及其所有内容
shutil.rmtree('source_directory')
注意事项
- 在使用
os.remove()
或shutil.rmtree()
删除文件或目录时,请确保这是你想要的操作的,因为删除后的文件或目录将无法恢复。 - 如果尝试删除的文件或目录不存在,这些函数会引发异常。在调用它们之前,你可能需要先检查文件或目录是否存在。
shutil.rmtree()
会递归删除目录及其所有内容,所以在使用时要特别小心,以免意外删除重要数据。
为了更安全地删除文件或目录,你可以考虑添加一些额外的检查或错误处理逻辑。例如,你可以使用os.path.exists()
来检查文件或目录是否存在,或者使用try-except
块来捕获并处理可能发生的异常。
import os
import shutil
# 检查文件是否存在并删除
file_path = 'source.txt'
if os.path.exists(file_path):
os.remove(file_path)
print(f"File {file_path} has been deleted.")
else:
print(f"File {file_path} does not exist.")
# 检查目录是否存在并删除
dir_path = 'source_directory'
if os.path.exists(dir_path):
shutil.rmtree(dir_path)
print(f"Directory {dir_path} has been deleted.")
else:
print(f"Directory {dir_path} does not exist.")
通过使用os.remove()
和shutil.rmtree()
,并结合适当的检查和错误处理,你可以在Python中安全地删除文件和目录。
三、 sys
1.1 基本介绍
sys是Python标准库中的一个模块,它提供了对Python解释器及其环境进行访问的功能。sys模块包含了一系列与Python解释器紧密相关的变量和函数,这些功能在开发和调试Python程序时非常有用。通过sys模块,我们可以获取Python解释器的版本信息、命令行参数、环境变量等,也可以对Python的运行环境进行一些基本的控制。
sys模块的主要功能包括但不限于:
-
访问命令行参数:sys模块提供了argv属性,它是一个包含命令行参数的列表。通过argv,我们可以获取用户在命令行中输入的参数,以便在程序中使用。
-
控制Python解释器:sys模块提供了一些函数,可以用于控制Python解释器的行为。例如,exit()函数可以退出Python程序,而executable属性则返回当前Python解释器的路径。
-
获取Python版本信息:通过sys模块的version和version_info属性,我们可以获取当前Python解释器的版本信息,这对于编写跨版本兼容的代码非常有用。
函数功能
在Python的sys
模块中,主要提供了与Python解释器和它的环境交互的变量和函数。虽然sys
模块中的函数大多用于底层的系统交互,但以下是其中一些重要的方法和它们的简单介绍:
sys.argv
这个列表包含了从命令行传入Python脚本的参数。sys.argv[0]
是脚本的名字(它作为脚本自身的路径),而sys.argv[1]
、sys.argv[2]
等则是额外的命令行参数。
示例:
import sys
# 假设脚本名为script.py,并从命令行调用:python script.py arg1 arg2
print(sys.argv) # 输出:['script.py', 'arg1', 'arg2']
sys.exit([arg])
执行一个系统退出。如果给出了参数,它会被返回给操作系统作为退出状态(在Unix系统中,0表示成功,非0表示错误)。
示例:
import sys
# 退出Python程序,返回状态码0
sys.exit(0)
sys.version
返回一个表示Python解释器版本信息的字符串。
示例:
import sys
print(sys.version) # 输出Python的版本信息,例如:3.8.5 (default, Jan 27 2021, 15:41:15) \n[GCC 9.3.0]
sys.path
一个列表,指定了解释器搜索模块的目录。初始化时使用从环境变量PYTHONPATH和程序的主目录中得到的值。
示例:
import sys
print(sys.path) # 输出Python解释器搜索模块的目录列表
sys.stdin
, sys.stdout
, sys.stderr
这些分别对应于解释器的标准输入、标准输出和标准错误流。它们通常被重定向到其他的输入/输出设备,如文件或网络连接。
示例:
import sys
# 读取一行从标准输入
input_data = sys.stdin.readline()
print(input_data, end='') # 将数据打印到标准输出
sys.modules
这是一个字典,将模块名映射到模块对象。这个字典在初始化时被填充,你可以在运行时修改它以影响import
语句。
示例:
import sys
# 查看已加载的模块
print(sys.modules.keys())
sys.platform
返回一个字符串,它标识运行Python解释器的平台。例如,对于Windows,它返回'win32'
,对于Linux/Unix,它可能返回'linux'
。
示例:
import sys
print(sys.platform) # 输出当前操作系统的平台标识符
请注意,sys
模块中的方法大多用于底层的系统交互和脚本的环境控制,并不是日常编程中经常使用的API。在大多数情况下,更高级的库和框架(如os
、shutil
等)提供了更为用户友好的接口来执行常见的系统任务。
四、 re
4.1 基本介绍
Python中的标准库re
,即正则表达式库,是Python用于处理正则表达式的核心库。正则表达式是一种强大的文本处理工具,它使用一种特殊的语法来匹配和操作字符串中的字符序列。re
库提供了正则表达式的编译和匹配操作,使Python程序员能够方便地在字符串中进行复杂的搜索和替换操作。
re
库的核心功能与作用主要体现在以下几个方面:
-
模式匹配:
re
库允许用户定义一种模式(即正则表达式),然后在目标字符串中搜索匹配该模式的子串。这使得re
库能够用于执行各种复杂的文本搜索任务,如查找特定的单词、数字、邮箱地址、URL等。 -
提取和分割字符串:除了匹配操作,
re
库还可以用于从字符串中提取特定的信息或根据正则表达式分割字符串。例如,你可以使用re
库从一段文本中提取所有的电子邮件地址,或者根据特定的分隔符将字符串拆分成多个部分。 -
替换和转换字符串:
re
库还提供了强大的字符串替换功能。你可以使用正则表达式来指定要替换的模式,并提供一个新的字符串来替换匹配到的内容。这使得re
库在文本清洗、格式化以及数据转换等任务中非常有用。 -
编译和缓存正则表达式:为了提高性能,
re
库支持正则表达式的编译和缓存。通过编译正则表达式,你可以将其转换为一个可重用的对象,以便在多次匹配操作中重复使用。此外,re
库还会自动缓存最近使用的正则表达式对象,以减少编译的开销。
总的来说,re
库是Python中处理字符串的强大工具,它使得复杂的文本搜索、提取、替换和转换操作变得简单而高效。无论你是在处理日志文件、解析HTML/XML文档还是进行数据分析,re
库都能为你提供强大的支持。
4.2 正则表达式的规则
正则表达式(Regular Expression,简称regex或regexp)本质上是一种特殊的字符串模式,用于在文本中执行搜索与替换操作。它通过预定义的元字符和模式来匹配字符串中的特定字符组合。正则表达式可以被视为一种描述字符串结构的语言,它定义了一个搜索模式,该模式描述了待搜索字符串的特征。
注: 下标来源于
文心一言
生成,人工过滤,可能仍然存在部分错误,请大家注意。
序号 | 规则 | 描述 | 示例 |
---|---|---|---|
1 | 直接匹配 | 字符在正则表达式中直接表示其字面含义,精确匹配该字符 | 表达式 ‘a’ 匹配字符串中的 ‘a’ |
2 | 数字匹配 | 使用 \d 匹配任意单个数字 | 表达式 ‘\d’ 匹配 ‘1’、‘2’、‘9’ 等 |
3 | 字母或数字匹配 | 使用 \w 匹配任意单个字母或数字 | 表达式 ‘\w’ 匹配 ‘a’、‘b’、‘1’、‘2’ 等 |
4 | 任意字符匹配 | 使用 . 匹配任意单个字符(除了换行符) | 表达式 ‘.’ 匹配 ‘a’、‘1’、‘!’ 等 |
5 | 空格匹配 | 使用 \s 匹配任意单个空格(包括Tab等空白符) | 表达式 ‘\s’ 匹配空格、Tab等 |
6 | 特殊字符转义 | 使用 \ 对特殊字符进行转义,以匹配其字面含义 | 表达式 \- 匹配 ‘-’ 字符 |
7 | 选择符匹配 | 使用 | 表示或关系,匹配其中之一即可 | 表达式 ‘a | b’ 匹配 ‘a’ 或 ‘b’ |
8 | 量词匹配 | 使用 {n} 、{n,} 、{n,m} 等表示前面的元素出现的次数 | 表达式 ‘\d{3}’ 匹配三位数字 |
9 | 字符串开始与结束匹配 | 使用 ^ 表示字符串的开始,$ 表示字符串的结束 | 表达式 ‘^Hello$’ 匹配整个字符串 “Hello” |
10 | 字符集匹配 | 使用 [] 定义字符集,匹配集合中的任意一个字符 | 表达式 ‘[abc]’ 匹配 ‘a’、‘b’ 或 ‘c’ |
11 | 否定字符集匹配 | 在字符集开始处使用 ^ 表示否定,匹配不在集合中的字符 | 表达式 [^abc] 匹配除了 ‘a’、‘b’ 和 ‘c’ 以外的任意字符 |
12 | 分组匹配 | 使用 () 对多个字符进行分组,可以作为一个整体进行匹配和引用 | 表达式 ‘(\d{3})-\d{4}’ 匹配形如 “123-4567” 的电话号码 |
13 | 边界匹配 | 使用 \b 和 \B 分别匹配单词边界和非单词边界 | 表达式 \bcat\b 匹配独立的单词 “cat” |
14 | 懒惰匹配 | 在量词后面使用 ? 进行懒惰匹配,尽可能少地匹配字符 | 表达式 ‘.*?b’ 匹配 “aab” 中的 “ab” |
15 | 前向肯定查找 | 使用 (?=...) 查找后面紧跟指定模式的字符串,但不包括该模式本身 | 表达式 ‘Windows(?=95 | 98 | NT | 2000)’ 匹配后面跟有指定版本的 “Windows” |
16 | 前向否定查找 | 使用 (?!...) 查找后面没有紧跟指定模式的字符串 | 表达式 ‘Windows(?!95 | 98 | NT | 2000)’ 匹配后面没有跟指定版本的 “Windows” |
4.3 re的实用方法
Python re
库重要方法介绍
re
库是 Python 中用于处理正则表达式的标准库,它提供了一系列方法和函数来执行正则表达式的匹配和替换操作。以下是 re
库中一些重要的方法及其描述和示例:
1. re.match(pattern, string, flags=0)
此方法从字符串的起始位置开始匹配正则表达式模式,如果起始位置匹配成功则返回一个匹配对象,否则返回 None
。
示例:
import re
# 匹配字符串开头的'Hello'
match = re.match(r'Hello', 'Hello, world!')
if match:
print("Match found:", match.group())
else:
print("No match")
2. re.search(pattern, string, flags=0)
此方法扫描整个字符串,并返回第一个成功匹配的匹配对象。如果字符串中没有匹配项,则返回 None
。
示例:
import re
# 在字符串中搜索'world'
search = re.search(r'world', 'Hello, world!')
if search:
print("Match found:", search.group())
else:
print("No match")
3. re.findall(pattern, string, flags=0)
此方法找到字符串中所有非重叠匹配项,并返回一个列表。
示例:
import re
# 找到字符串中所有的数字
matches = re.findall(r'\d+', 'There are 123 apples and 456 oranges.')
print("Matches found:", matches) # 输出: ['123', '456']
4. re.finditer(pattern, string, flags=0)
此方法找到字符串中所有匹配项,并返回一个迭代器,其中每个迭代项是一个匹配对象。
示例:
import re
# 找到字符串中所有的数字,并打印每个匹配项的位置和值
matches = re.finditer(r'\d+', 'There are 123 apples and 456 oranges.')
for match in matches:
print("Position:", match.start(), "-", match.end(), "Value:", match.group())
5. re.sub(pattern, repl, string, count=0, flags=0)
此方法使用 repl
替换字符串中所有匹配正则表达式的子串。count
参数可以指定最大替换次数。
示例:
import re
# 将字符串中的数字替换为'NUM'
new_string = re.sub(r'\d+', 'NUM', 'There are 123 apples and 456 oranges.')
print(new_string) # 输出: There are NUM apples and NUM oranges.
6. re.compile(pattern, flags=0)
此方法将正则表达式的字符串形式编译成一个正则表达式对象,供后续使用。
示例:
import re
# 编译一个正则表达式对象
pattern = re.compile(r'\d+')
# 使用编译后的对象进行匹配
match = pattern.search('There are 123 apples.')
if match:
print("Match found:", match.group())
当然还有许多其他的匹配功能,但篇幅有限这里不做展开了。
五、 json
5.1 基本介绍
在Python中,标准库json
是用来处理JSON(JavaScript Object Notation)数据格式的。JSON是一种轻量级的数据交换格式,它基于ECMAScript的一个子集,采用完全独立于语言的文本格式来存储和表示数据。简单、清晰的层次结构使得JSON成为理想的数据交换语言。
5.2 json的使用方法
json
是 Python 的标准库之一,主要用于编码(序列化)和解码(反序列化)JSON 数据格式。JSON (JavaScript Object Notation) 是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。
以下是 json
库按照不同功能用途的分类,以及每个功能的具体使用方法和案例介绍:
4.2.1 编码(序列化)
将 Python 对象转换为 JSON 格式的字符串。
json.dumps(obj, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw)
将 Python 对象 obj
转换为一个 JSON 格式的字符串。
示例:
import json
data = {
"name": "Alice",
"age": 30,
"is_student": False
}
json_string = json.dumps(data)
print(json_string) # 输出: {"name": "Alice", "age": 30, "is_student": false}
4.2.2 解码(反序列化)
将 JSON 格式的字符串转换为 Python 对象。
json.loads(s, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)
将 JSON 格式的字符串 s
转换为一个 Python 对象。
示例:
import json
json_string = '{"name": "Alice", "age": 30, "is_student": false}'
data = json.loads(json_string)
print(data) # 输出: {'name': 'Alice', 'age': 30, 'is_student': False}
4.2.3 文件读写
直接读取或写入 JSON 数据到文件。
json.dump(obj, fp, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw)
将 Python 对象 obj
编码为 JSON 格式并写入文件对象 fp
。
示例:
import json
data = {
"name": "Alice",
"age": 30,
"is_student": False
}
with open('data.json', 'w') as f:
json.dump(data, f)
json.load(fp, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)
从文件对象 fp
读取 JSON 格式的数据,并返回一个 Python 对象。
示例:
import json
with open('data.json', 'r') as f:
data = json.load(f)
print(data) # 输出: {'name': 'Alice', 'age': 30, 'is_student': False}
这些功能涵盖了 json
库的主要用途:将 Python 对象转换为 JSON 字符串,将 JSON 字符串转换为 Python 对象,以及直接对文件进行 JSON 数据的读写操作。在实际应用中,这些功能可以帮助我们轻松地处理 JSON 数据,实现数据的序列化和反序列化,以及与文件系统的交互。
六、 pickle
6.1 基本介绍
与json相似的还有pickle
这个标准库。pickle
是 Python 的一个标准库,用于序列化和反序列化 Python 对象结构。序列化是将对象的状态信息转换为可以存储或传输的形式的过程,而反序列化则是将这个形式转换回原始对象的过程。pickle
库特别适用于将 Python 对象保存为持久的二进制格式,以便将来可以恢复这些对象的状态。
6.2 pickle的使用方法
6.2.1 序列化(对象到字节流)
pickle.dumps(obj, protocol=None, *, fix_imports=True)
将 Python 对象 obj
序列化为字节流。
示例:
import pickle
# 定义一个简单的 Python 对象
data = {
"name": "Alice",
"age": 30,
"is_student": False
}
# 将对象序列化为字节流
serialized_data = pickle.dumps(data)
# 输出序列化后的字节流(通常是不可读的二进制数据)
print(serialized_data)
6.2.2 反序列化(字节流到对象)
pickle.loads(bytes_object, *, fix_imports=True, encoding="bytes", errors="strict")
从字节流 bytes_object
中反序列化出 Python 对象。
示例:
import pickle
# 假设我们有之前序列化得到的字节流
serialized_data = b'\x80\x04\x95\x1f\x00\x00\x00\x00\x00\x00\x00\x8c\x1b{\x22name\x22: \x22Alice\x22, \x22age\x22: 30, \x22is_student\x22: False}\x94.'
# 从字节流中反序列化出 Python 对象
loaded_data = pickle.loads(serialized_data)
# 输出反序列化后的对象
print(loaded_data) # 输出: {'name': 'Alice', 'age': 30, 'is_student': False}
6.2.3 序列化到文件
pickle.dump(obj, file, protocol=None, *, fix_imports=True)
将 Python 对象 obj
序列化为字节流并写入到文件对象 file
中。
示例:
import pickle
# 定义一个简单的 Python 对象
data = {
"name": "Alice",
"age": 30,
"is_student": False
}
# 将对象序列化并写入文件
with open('data.pkl', 'wb') as f:
pickle.dump(data, f)
6.2.4 从文件反序列化
pickle.load(file, *, fix_imports=True, encoding="bytes", errors="strict")
从文件对象 file
中读取序列化的字节流并反序列化出 Python 对象。
示例:
import pickle
# 从文件中反序列化对象
with open('data.pkl', 'rb') as f:
loaded_data = pickle.load(f)
# 输出反序列化后的对象
print(loaded_data) # 输出: {'name': 'Alice', 'age': 30, 'is_student': False}
注意事项:
pickle
序列化的数据格式是 Python 特有的,因此它只能被 Python 程序读取和反序列化。- 由于
pickle
可以执行任意代码,因此从不受信任的来源加载数据是不安全的。这可能导致代码注入攻击。 protocol
参数用于指定序列化时使用的协议版本。不同的协议版本在兼容性和效率方面有所不同。默认情况下,pickle
使用最高版本的协议。
pickle
库为 Python 提供了强大的对象序列化和反序列化功能,使得对象可以方便地在不同时间、不同空间或不同程序之间进行传输和存储。然而,使用时需要谨慎,特别是在处理来自不受信任来源的数据时。
七、 random
7.1 基本介绍
Python的标准库random
提供了生成随机数的功能,使得开发者能够在程序中引入随机性。这个库在模拟、游戏、测试、密码学等多个领域都有广泛的应用。
7.2 random的使用方法
7.2.1 random随机数生成
random.randint(a, b)
这个函数用于生成一个指定范围内的随机整数,包括a
和b
。
示例:
import random
# 生成一个1到10(包括1和10)之间的随机整数
random_int = random.randint(1, 10)
print(random_int)
random.randrange(start, stop[, step])
这个函数用于生成一个指定范围内的随机整数,范围从start
到stop
(不包括stop
),如果提供了step
参数,则步长为step
。
示例:
import random
# 生成一个0到9(不包括10)之间的随机整数
random_range_no_step = random.randrange(10)
print(random_range_no_step)
# 生成一个0到100之间,步长为10的随机整数
random_range_with_step = random.randrange(0, 101, 10)
print(random_range_with_step)
random.random()
这个函数用于生成一个[0.0, 1.0)之间的随机浮点数。
示例:
import random
# 生成一个[0.0, 1.0)之间的随机浮点数
random_float = random.random()
print(random_float)
random.uniform(a, b)
这个函数用于生成一个指定范围内的随机浮点数,范围从a
到b
。
示例:
import random
# 生成一个2.5到7.5之间的随机浮点数
random_uniform = random.uniform(2.5, 7.5)
print(random_uniform)
7.2.2 从指定序列中生成随机数
random.choice(seq)
功能:从非空序列seq
中随机选择一个元素。
示例:
import random
fruits = ['apple', 'banana', 'cherry']
chosen_fruit = random.choice(fruits)
print(chosen_fruit) # 输出可能是 'apple'、'banana' 或 'cherry' 中的任意一个
random.choices(seq, weights=None, *, cum_weights=None, k=1)
功能:从序列seq
中随机选择k
个元素,可以指定每个元素的权重。
示例:
import random
fruits = ['apple', 'banana', 'cherry']
weights = [1, 3, 1] # banana 的权重是 apple 和 cherry 的三倍
chosen_fruits = random.choices(fruits, weights=weights, k=2)
print(chosen_fruits) # 输出可能是包含 'banana' 的两个元素的列表,因为 banana 的权重更高
random.sample(seq, k)
功能:从序列seq
中随机选择k
个不重复的元素。
示例:
import random
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
selected_numbers = random.sample(numbers, 3)
print(selected_numbers) # 输出可能是 [2, 5, 9] 或其他三个不重复的数字组合
random.shuffle(seq)
功能:随机打乱序列seq
中的元素顺序。
示例:
import random
deck = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']
random.shuffle(deck)
print(deck) # 输出可能是被打乱顺序的牌组,如 ['4', 'J', 'A', '3', ...]
请注意,random.choices()
函数中的weights
参数用于指定每个元素被选中的概率,而cum_weights
参数是一个累积权重列表,用于指定每个元素之前的所有元素的累积权重。当使用weights
参数时,不需要提供cum_weights
。
random.sample()
函数和random.choice()
函数的主要区别在于,random.sample()
能够返回指定数量的不重复元素,而random.choice()
只返回单个元素。
random.shuffle()
函数则直接对传入的序列进行原地打乱,即修改传入的序列本身,而不是返回一个新的序列。
7.2.3 生成特定分布的随机数
random.uniform(a, b)
功能:生成一个[a, b)之间的随机浮点数,即均匀分布。
示例:
import random
# 生成一个[1.0, 5.0)之间的随机浮点数
random_uniform = random.uniform(1.0, 5.0)
print(random_uniform) # 输出类似 2.345678901234567
random.normalvariate(mu, sigma)
功能:生成一个正态(高斯)分布的随机浮点数,其中mu
是均值,sigma
是标准差。
示例:
import random
# 生成一个均值为0,标准差为1的正态分布随机浮点数
random_normal = random.normalvariate(0.0, 1.0)
print(random_normal) # 输出类似 -0.1234567890123456
random.betavariate(alpha, beta)
功能:生成一个Beta分布的随机浮点数,其中alpha
和beta
是分布参数。
示例:
import random
# 生成一个alpha为2,beta为5的Beta分布随机浮点数
random_beta = random.betavariate(2.0, 5.0)
print(random_beta) # 输出类似 0.2345678901234567
random.expovariate(lambd)
功能:生成一个指数分布的随机浮点数,其中lambd
是分布率(即每单位时间发生事件的平均次数)。
示例:
import random
# 生成一个lambd为0.5的指数分布随机浮点数
random_expo = random.expovariate(0.5)
print(random_expo) # 输出类似 1.234567890123456
random.gammavariate(alpha, beta)
功能:生成一个Gamma分布的随机浮点数,其中alpha
是形状参数,beta
是尺度参数。
示例:
import random
# 生成一个alpha为2,beta为1的Gamma分布随机浮点数
random_gamma = random.gammavariate(2.0, 1.0)
print(random_gamma) # 输出类似 1.234567890123456
random.paretovariate(alpha)
功能:生成一个Pareto分布的随机浮点数,其中alpha
是形状参数。
示例:
import random
# 生成一个alpha为3的Pareto分布随机浮点数
random_pareto = random.paretovariate(3.0)
print(random_pareto) # 输出类似 1.234567890123456
random.weibullvariate(alpha, beta)
功能:生成一个Weibull分布的随机浮点数,其中alpha
是形状参数,beta
是尺度参数。
示例:
import random
# 生成一个alpha为2,beta为1的Weibull分布随机浮点数
random_weibull = random.weibullvariate(2.0, 1.0)
print(random_weibull) # 输出类似 1.234567890123456
random.triangular(low, high, mode)
功能:生成一个三角分布的随机浮点数,其中low
是分布的下限,high
是分布的上限,mode
是分布众数。
示例:
import random
# 生成一个在[2, 8)之间,众数为5的三角分布随机浮点数
random_triangular = random.triangular(2, 8, 5)
print(random_triangular) # 输出类似 4.56789012345678
random.lognormvariate(mu, sigma)
功能:生成一个对数正态分布的随机浮点数,其中mu
是对数均值,sigma
是对数标准差。
示例:
import random
# 生成一个对数均值为0,对数标准差为1的对数正态分布随机浮点数
random_lognorm = random.lognormvariate(0.0, 1.0)
print(random_lognorm) # 输出类似 1.234567890123456
random.getrandbits(k)
功能:生成一个包含k
个随机比特位的整数。
示例:
import random
# 生成一个包含10个随机比特位的整数
random_bits = random.getrandbits(10)
print(random_bits) # 输出类似 567(一个10位二进制数对应的十进制数)
八、math
8.1 基本介绍
math
库是Python的一个内置标准库,无需额外安装即可使用。它提供了对常见数学运算和函数的支持,涵盖了基础数学、三角函数、指数和对数函数、常数等多个方面。通过这个库,你可以轻松地进行各种数学计算,而无需自己编写复杂的算法。
math
库的主要功能可以分为以下几类:
- 常数:如圆周率π、自然对数的底e等,这些常数在数学计算中经常用到。
- 基础数学运算:包括加法、减法、乘法、除法等基本运算,以及求绝对值、最大值、最小值等常用操作,同时还有求对数、次方等。
- 三角函数:如正弦(sine)、余弦(cosine)、正切(tangent)等,以及它们的反函数(如反正弦、反余弦等)。这些函数在处理与角度和三角形相关的问题时非常有用。
- 特殊函数:如阶乘(factorial)、伽马函数(gamma function)等,用于处理更复杂的数学问题。
8.2 math的使用方法
8.2.1 常数
在Python的math
库中,有几个重要的数学常数,这些常数在进行数学计算时经常被使用。以下是其中一些重要的数学常数:
math.pi
math.pi
表示圆周率π,即圆的周长与直径的比值。它是一个无理数,其值约等于3.141592653589793。在涉及圆的计算,如计算圆的面积或周长时,math.pi
非常有用。
示例:
import math
# 计算圆的面积
radius = 5
area = math.pi * radius ** 2
print(area)
math.e
math.e
表示自然对数的底数e,约等于2.718281828459045。在涉及指数函数、对数函数或复利计算的数学问题中,math.e
经常被使用。
示例:
import math
# 计算e的2次方
result = math.e ** 2
print(result)
math.tau
math.tau
代表一个数学常数,等于2π,即圆的周长与半径的比值。这个常数在2019年的Python 3.6版本中被引入,用于简化与圆相关的计算。
示例:
import math
# 使用tau计算圆的周长
radius = 5
circumference = math.tau * radius
print(circumference)
math.inf
math.inf
表示正无穷大,用于表示比任何其他浮点数都要大的数值。这在某些数学运算和比较中很有用,例如,在寻找最大值时,如果无法确定实际的最大值,可以使用math.inf
作为初始值。
示例:
import math
# 初始化一个无穷大的最小值
min_value = math.inf
# 假设有一个数列,找到其中的最小值
numbers = [4, 2, 9, 7, 5]
for number in numbers:
if number < min_value:
min_value = number
print(min_value) # 输出:2
math.nan
math.nan
表示非数字(Not a Number),是一个特殊的浮点数值,用于表示某些未定义或不可表示的结果,如0除以0。
示例:
import math
# 计算0除以0,得到nan
result = 0 / 0
print(result is math.nan) # 输出:True
8.2.2 数论与表示函数
在Python的math
库中,数论与表示函数提供了多种工具,用于处理数学运算中涉及整数和浮点数的特定情况。以下是一些重要的数论与表示函数及其相关知识:
math.ceil(x)
math.ceil(x)
函数返回大于或等于x的最小整数。这在需要向上取整的场景中非常有用。
示例:
import math
# 向上取整
result = math.ceil(3.14)
print(result) # 输出:4
math.floor(x)
math.floor(x)
函数返回小于或等于x的最大整数。这在需要向下取整的场景中很有用。
示例:
import math
# 向下取整
result = math.floor(3.14)
print(result) # 输出:3
math.fabs(x)
math.fabs(x)
函数返回x的绝对值。它对于处理可能为负数的数值特别有用。
示例:
import math
# 计算绝对值
result = math.fabs(-3.14)
print(result) # 输出:3.14
math.factorial(x)
math.factorial(x)
函数返回x的阶乘,即x的所有正整数的乘积。这在组合数学和概率论中非常有用。
示例:
import math
# 计算阶乘
result = math.factorial(5)
print(result) # 输出:120
math.gcd(a, b)
math.gcd(a, b)
函数返回整数a和b的最大公约数。最大公约数是两个或多个整数共有约数中最大的一个。
示例:
import math
# 计算最大公约数
result = math.gcd(48, 18)
print(result) # 输出:6
math.isclose(a, b, rel_tol=1e-09, abs_tol=0.0)
math.isclose(a, b, rel_tol=1e-09, abs_tol=0.0)
函数用于比较两个浮点数a和b是否接近相等,考虑了相对容差和绝对容差。这在比较浮点数时特别有用,因为直接比较可能会由于精度问题而导致不准确的结果。
示例:
import math
# 检查浮点数是否接近相等
result = math.isclose(0.1 + 0.2, 0.3)
print(result) # 输出:True
math.isfinite(x)
math.isfinite(x)
函数检查x是否是一个有限数,即既不是无穷大也不是NaN(非数字)。
示例:
import math
# 检查是否为有限数
result = math.isfinite(10.0)
print(result) # 输出:True
math.isinf(x)
math.isinf(x)
函数检查x是否是正无穷大或负无穷大。
示例:
import math
# 检查是否为无穷大
result = math.isinf(float('inf'))
print(result) # 输出:True
math.isnan(x)
math.isnan(x)
函数检查x是否是NaN(非数字)。这在处理浮点数运算结果时非常有用,因为某些操作(如0除以0)会导致结果无法定义,从而返回NaN。
示例:
import math
# 检查是否为NaN
result = math.isnan(0 / 0)
print(result) # 输出:True
math.pow(x, y)
math.pow(x, y)
函数返回x的y次方,即x乘以自身y次。这是计算幂运算的简便方式。
示例:
import math
# 计算幂
result = math.pow(2, 3)
print(result) # 输出:8.0
math.sqrt(x)
math.sqrt(x)
函数返回x的平方根。它用于计算非负实数的平方根。
示例:
import math
# 计算平方根
result = math.sqrt(9)
print(result) # 输出:3.
当然,我们继续介绍math
库中的数论与表示函数:
math.trunc(x)
math.trunc(x)
函数返回x的整数部分,即去掉小数部分后的结果。它相当于向零取整,对于正数,返回不大于x的最大整数;对于负数,返回不小于x的最大整数。
示例:
import math
# 截断小数部分
result = math.trunc(3.14)
print(result) # 输出:3
result = math.trunc(-3.14)
print(result) # 输出:-3
math.fmod(x, y)
math.fmod(x, y)
函数返回x除以y的余数。与x % y
不同,fmod()
函数的结果的符号与x相同,这对于需要保持余数与被除数符号一致的场景非常有用。
示例:
import math
# 计算余数
result = math.fmod(7, 3)
print(result) # 输出:1.0
result = math.fmod(-7, 3)
print(result) # 输出:-1.0
math.frexp(x)
math.frexp(x)
函数返回一个元组,其中包含x的尾数和指数。尾数是一个在[0.5, 1.0)或(-1.0, -0.5]区间内的浮点数,而指数是一个整数,表示x等于尾数乘以2的指数的次方。这个函数用于分解浮点数的表示。
示例:
import math
# 分解浮点数的尾数和指数
mantissa, exponent = math.frexp(0.75)
print(mantissa, exponent) # 输出:0.5 1
math.ldexp(x, i)
math.ldexp(x, i)
函数返回x乘以(2的i次方)的结果。它通常与frexp()
函数一起使用,用于将尾数和指数重新组合成原始浮点数。
示例:
import math
# 将尾数和指数组合成浮点数
mantissa, exponent = math.frexp(0.75)
result = math.ldexp(mantissa, exponent)
print(result) # 输出:0.75
math.modf(x)
math.modf(x)
函数返回x的小数部分和整数部分,作为一对(frac, int)元组。小数部分是一个浮点数,表示x的小数部分,而整数部分是一个浮点数,表示x的整数部分(但总是0,除非x本身是整数)。
示例:
import math
# 分解整数和小数部分
frac, int_part = math.modf(3.14)
print(frac, int_part) # 输出:0.14000000000000012 3.0
8.2.3 幂函数与对数函数
在Python的math库中,与幂函数相关的主要方法有math.pow()
和math.exp()
。
math.pow(x, y)
这个函数返回x的y次幂,即xy。x和y都是浮点数,如果x为负数且y不是整数,那么结果是一个复数。
示例:
import math
# 计算2的3次幂
result = math.pow(2, 3)
print(result) # 输出:8.0
math.exp(x)
这个函数返回e的x次幂,其中e是自然对数的底数(约等于2.71828)。
示例:
import math
# 计算e的2次幂
result = math.exp(2)
print(result) # 输出:7.3890560989306495
math库中与对数函数相关的主要方法有math.log()
, math.log2()
, math.log10()
等。
math.log(x, [base])
这个函数返回x的自然对数(以e为底),如果提供了可选参数base,则返回x的对数,以base为底。如果省略base,则返回x的自然对数。
示例:
import math
# 计算2的自然对数
result_natural = math.log(2)
print(result_natural) # 输出:0.6931471805599453
# 计算10的以2为底的对数
result_base2 = math.log(10, 2)
print(result_base2) # 输出:约等于3.321928094887362
math.log2(x)
这个函数返回x的以2为底的对数。
示例:
import math
# 计算8的以2为底的对数
result = math.log2(8)
print(result) # 输出:3.0
math.log10(x)
这个函数返回x的以10为底的对数。
示例:
import math
# 计算100的以10为底的对数
result = math.log10(100)
print(result) # 输出:2.0
这些函数在处理与幂和对数相关的数学问题时非常有用,可以帮助我们更轻松地进行复杂的数学运算。
8.2.4 三角函数
在Python的math
库中,提供了基本的三角函数功能,这些函数允许我们进行角度和弧度之间的转换,并计算正弦、余弦、正切等三角函数的值。
math.sin(x)
这个函数返回x
(以弧度为单位)的正弦值。
示例:
import math
# 计算π/2的正弦值(应为1)
result = math.sin(math.pi / 2)
print(result) # 输出:约等于1.0
math.cos(x)
这个函数返回x
(以弧度为单位)的余弦值。
示例:
import math
# 计算0的余弦值(应为1)
result = math.cos(0)
print(result) # 输出:1.0
math.tan(x)
这个函数返回x
(以弧度为单位)的正切值。
示例:
import math
# 计算π/4的正切值(应为1)
result = math.tan(math.pi / 4)
print(result) # 输出:约等于1.0
math.asin(x)
这个函数返回x
的反正弦值(以弧度为单位),其值域为[-π/2, π/2]
。
示例:
import math
# 计算1的反正弦值(应为π/2)
result = math.asin(1)
print(result) # 输出:约等于1.5707963267948966(即π/2)
math.acos(x)
这个函数返回x
的反余弦值(以弧度为单位),其值域为[0, π]
。
示例:
import math
# 计算1的反余弦值(应为0)
result = math.acos(1)
print(result) # 输出:0.0
math.atan(x)
这个函数返回x
的反正切值(以弧度为单位),其值域为[-π/2, π/2]
。
示例:
import math
# 计算1的反正切值(应为π/4)
result = math.atan(1)
print(result) # 输出:约等于0.7853981633974483(即π/4)
math.atan2(y, x)
这个函数返回从X轴到点(x, y)的向量与X轴正向之间的夹角(以弧度为单位),其值域为[-π, π]
。这个函数考虑了Y和X的符号,因此可以确定角度是在哪个象限。
示例:
import math
# 计算从X轴到点(1, 1)的向量与X轴正向之间的夹角(应为π/4)
result = math.atan2(1, 1)
print(result) # 输出:约等于0.7853981633974483(即π/4)
使用这些函数时,请确保你了解输入值应该是以弧度为单位,而不是度数。如果你有一个角度值(以度为单位),你需要先将其转换为弧度,可以使用math.radians(x)
函数来完成这个转换。同样,如果你想要将弧度值转换回角度,可以使用math.degrees(x)
函数。
8.2.5 双曲函数
在Python的math
库中,也包含了一系列双曲函数,这些函数在处理某些复杂的数学问题时非常有用。双曲函数在物理学、工程学以及某些数学分支(如复分析和微分方程)中都有广泛的应用。
math.sinh(x)
这个函数返回x
的双曲正弦值。
示例:
import math
# 计算1的双曲正弦值
result = math.sinh(1)
print(result) # 输出:约等于1.1752011936438014
math.cosh(x)
这个函数返回x
的双曲余弦值。
示例:
import math
# 计算0的双曲余弦值(应为1)
result = math.cosh(0)
print(result) # 输出:1.0
math.tanh(x)
这个函数返回x
的双曲正切值。
示例:
import math
# 计算1的双曲正切值
result = math.tanh(1)
print(result) # 输出:约等于0.7615941559557649
math.asinh(x)
这个函数返回x
的反双曲正弦值。
示例:
import math
# 计算1的反双曲正弦值
result = math.asinh(1)
print(result) # 输出:约等于0.8813735870195430
math.acosh(x)
这个函数返回x
的反双曲余弦值。注意,x
必须大于等于1,因为对于小于1的x
值,反双曲余弦是未定义的。
示例:
import math
# 计算2的反双曲余弦值
result = math.acosh(2)
print(result) # 输出:约等于1.3169578969248166
math.atanh(x)
这个函数返回x
的反双曲正切值。注意,x
必须在-1和1之间(包括-1和1),因为对于超出这个范围的x
值,反双曲正切是未定义的。
示例:
import math
# 计算0.5的反双曲正切值
result = math.atanh(0.5)
print(result) # 输出:约等于0.5493061443340549
双曲函数在处理某些特定的物理问题(如相对论力学)和复杂的数学问题(如偏微分方程)时非常有用。通过math
库中的这些函数,Python程序员可以方便地进行双曲函数的计算。
8.2.6 特殊函数
在Python的math
库中,除了常见的三角函数、双曲函数以及基本的数学运算函数外,还提供了一些特殊函数。这些特殊函数在处理一些复杂或特殊的数学问题时非常有用。
math.gamma(x)
这个函数返回x
的伽马函数值。伽马函数在复数平面上除了负整数和非正整数外都有定义,并在实数域上为正数。它在统计、积分等领域有着广泛的应用。
示例:
import math
# 计算0.5的伽马函数值(应为sqrt(pi))
result = math.gamma(0.5)
print(result) # 输出:约等于1.772453850905516
math.lgamma(x)
这个函数返回x
的伽马函数的自然对数值以及它的符号。它通常用于计算大数的伽马函数值,以避免数值溢出。
math.erf(x)
这个函数返回x
的误差函数值。误差函数是标准正态分布的累积分布函数。
示例:
import math
# 计算1的误差函数值
result = math.erf(1)
print(result) # 输出:约等于0.842700792949715
math.erfc(x)
这个函数返回x
的互补误差函数值,即1减去误差函数值。它常用于计算尾部概率。
math.log1p(x)
这个函数返回1+x
的自然对数。当x
很小且接近0时,log1p(x)
的计算通常比log(1+x)
更准确,因为它避免了直接相加可能导致的数值不稳定问题。
示例:
import math
# 计算log(1+0.00001)的近似值
result = math.log1p(0.00001)
print(result) # 输出:约等于0.00000999995000003
math.expm1(x)
这个函数返回e
的x
次方减1,即exp(x) - 1
。当x
很小且接近0时,expm1(x)
的计算通常比exp(x) - 1
更准确。
示例:
import math
# 计算exp(0.00001) - 1的近似值
result = math.expm1(0.00001)
print(result) # 输出:约等于0.00001000005000005
这些特殊函数在统计计算、物理学、工程学等领域中经常被使用,用于处理各种复杂的数学问题。通过使用Python的math
库,我们可以方便地调用这些函数,而无需自己编写相应的算法。
九、 itertools
9.1 基本介绍
itertools
模块的存在是为了简化复杂的迭代操作,使开发者能够用简洁的代码创建复杂的迭代器,从而实现对集合元素的组合、排列、筛选等操作。这个模块不仅提高了代码的可读性,还优化了性能,因为它在内部采用了高效的数据结构和算法。
主要功能介绍:
itertools
模块的主要功能可以分为以下几类:
- 基本迭代器:提供无限迭代器,如
count()
、cycle()
和repeat()
,用于生成无限序列或重复序列。 - 组合迭代器:如
combinations()
、combinations_with_replacement()
和permutations()
,用于生成输入迭代器的组合或排列。 - 筛选迭代器:如
filterfalse()
和compress()
,用于根据条件筛选迭代器中的元素。 - 累加和分组迭代器:如
accumulate()
和groupby()
,用于对迭代器中的元素进行累加或分组操作。
这些功能只是itertools
模块的一部分,实际上它还提供了更多高级功能,可以帮助你更高效地处理复杂的迭代任务。
通过使用itertools
模块,你可以避免编写冗长且容易出错的代码,同时提高程序的性能和效率。这个模块是Python编程中的一大利器,尤其是对于需要处理大量数据或进行复杂迭代操作的开发者来说,它无疑是一个不可或缺的工具。
9.2 itertools的使用方法
9.2.1 基本迭代器
在Python的itertools
模块中,提供了一些用于创建无限迭代器的函数。无限迭代器可以持续不断地产生值,直到程序终止或显式地停止迭代。以下是一些关键的无限迭代器及其用法:
itertools.count()
itertools.count()
函数会创建一个迭代器,该迭代器从指定的起始值开始,无限递增地产生整数。如果不提供起始值,则默认从0开始。
示例:
import itertools
# 创建一个从1开始的无限递增迭代器
counter = itertools.count(1)
# 打印前5个值
for i in range(5):
print(next(counter)) # 输出:1 2 3 4 5
itertools.cycle()
itertools.cycle()
函数会创建一个迭代器,该迭代器会无限循环遍历传入的序列。
示例:
import itertools
# 创建一个无限循环遍历'a', 'b', 'c'的迭代器
cycler = itertools.cycle('abc')
# 打印前5个值
for i in range(5):
print(next(cycler)) # 输出:'a' 'b' 'c' 'a' 'b'
itertools.repeat()
itertools.repeat()
函数会创建一个迭代器,该迭代器会无限重复指定的元素。可以通过提供第二个参数来指定重复的次数,如果不提供则默认无限重复。
示例:
import itertools
# 创建一个无限重复'x'的迭代器
repeater = itertools.repeat('x')
# 打印前5个值
for i in range(5):
print(next(repeater)) # 输出:'x' 'x' 'x' 'x' 'x'
# 创建一个重复'y' 3次的迭代器
limited_repeater = itertools.repeat('y', 3)
# 打印所有值
for value in limited_repeater:
print(value) # 输出:'y' 'y' 'y'
9.2.2 组合迭代器
组合迭代器
在Python的itertools
模块中,组合迭代器用于生成输入迭代器的元素的不同组合。这些组合迭代器在处理数据集的排列组合问题时非常有用。以下是一些关键的组合迭代器及其用法:
itertools.product(*iterables, repeat=1)
itertools.product
函数用于计算笛卡尔积,即输入迭代器的所有可能的组合。
示例:
import itertools
# 生成A和B的笛卡尔积
A = [1, 2]
B = ['a', 'b']
product_iter = itertools.product(A, B)
# 打印所有组合
for combo in product_iter:
print(combo) # 输出:(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')
itertools.permutations(iterable, r=None)
itertools.permutations
函数用于生成输入迭代器的所有可能排列。r
参数用于指定排列的长度,如果省略或为None
,则排列长度与输入迭代器相同。
示例:
import itertools
# 生成['a', 'b', 'c']的所有排列
permutations_iter = itertools.permutations(['a', 'b', 'c'])
# 打印前3个排列
for i in range(3):
print(next(permutations_iter)) # 输出:('a', 'b', 'c'), ('a', 'c', 'b'), ('b', 'a', 'c')
itertools.combinations(iterable, r)
itertools.combinations
函数用于生成输入迭代器的所有长度为r
的组合,不考虑元素的顺序。
示例:
import itertools
# 生成[1, 2, 3, 4]的所有长度为2的组合
combinations_iter = itertools.combinations([1, 2, 3, 4], 2)
# 打印所有组合
for combo in combinations_iter:
print(combo) # 输出:(1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)
itertools.combinations_with_replacement(iterable, r)
itertools.combinations_with_replacement
函数与combinations
类似,但允许元素在组合中重复出现。
示例:
import itertools
# 生成[1, 2]的所有长度为2的组合,允许重复
combinations_with_replacement_iter = itertools.combinations_with_replacement([1, 2], 2)
# 打印所有组合
for combo in combinations_with_replacement_iter:
print(combo) # 输出:(1, 1), (1, 2), (2, 2)
9.2.3 筛选迭代器
筛选迭代器
在Python的itertools
模块中,筛选迭代器用于从输入迭代器中筛选出满足特定条件的元素。这些迭代器可以帮助我们高效地处理数据,只关注我们感兴趣的部分。以下是一些关键的筛选迭代器及其用法:
itertools.filterfalse(predicate, iterable)
itertools.filterfalse
函数用于从输入迭代器iterable
中筛选出那些使得predicate
函数返回False
的元素。这与内置的filter
函数相反,filter
函数筛选的是返回True
的元素。
示例:
import itertools
# 定义一个函数,判断一个数是否为偶数
def is_even(n):
return n % 2 == 0
# 生成一个包含1到5的迭代器
numbers = range(1, 6)
# 使用filterfalse筛选出不是偶数的数
filtered_iter = itertools.filterfalse(is_even, numbers)
# 打印筛选结果
for num in filtered_iter:
print(num) # 输出:1 3 5
itertools.compress(data, selectors)
itertools.compress
函数根据selectors
迭代器中的布尔值来筛选data
迭代器中的元素。当selectors
中的值为True
时,对应的data
中的元素会被保留。
示例:
import itertools
# 定义一个数据迭代器
data = ['a', 'b', 'c', 'd', 'e']
# 定义一个选择器迭代器,表示哪些数据应该被保留
selectors = [True, False, True, False, True]
# 使用compress筛选出被保留的元素
compressed_iter = itertools.compress(data, selectors)
# 打印筛选结果
for item in compressed_iter:
print(item) # 输出:a c e
itertools.dropwhile(predicate, iterable)
itertools.dropwhile
函数会丢弃输入迭代器iterable
中连续满足predicate
函数的元素,直到遇到第一个不满足的元素,然后返回剩余的元素。
示例:
import itertools
# 定义一个函数,判断一个数是否小于等于3
def is_leq_3(n):
return n <= 3
# 生成一个包含1到5的迭代器
numbers = range(1, 6)
# 使用dropwhile丢弃小于等于3的数
dropped_iter = itertools.dropwhile(is_leq_3, numbers)
# 打印剩余元素
for num in dropped_iter:
print(num) # 输出:4 5
itertools.takewhile(predicate, iterable)
itertools.takewhile
函数与dropwhile
相反,它会返回输入迭代器iterable
中连续满足predicate
函数的元素,直到遇到第一个不满足的元素为止。
示例:
import itertools
# 定义一个函数,判断一个数是否小于等于3
def is_leq_3(n):
return n <= 3
# 生成一个包含1到5的迭代器
numbers = range(1, 6)
# 使用takewhile获取小于等于3的数
taken_iter = itertools.takewhile(is_leq_3, numbers)
# 打印获取的元素
for num in taken_iter:
print(num) # 输出:1 2 3
这些筛选迭代器为处理数据提供了灵活且高效的方式,使我们能够根据特定的条件来过滤和选择数据。
9.3.4 累加和分组迭代器
在Python的itertools
模块中,累加和分组迭代器用于处理输入迭代器的元素,以便将它们以某种特定的累加方式分组。这些迭代器在处理序列数据、进行累加操作或分组操作时非常有用。
itertools.accumulate(iterable[, func])
itertools.accumulate
函数返回一个迭代器,它产生累加结果。每次迭代都会计算当前元素与前一个累加结果的和(或根据提供的func
函数进行其他操作)。
示例:
import itertools
# 生成一个包含数字的迭代器
numbers = [1, 2, 3, 4, 5]
# 使用accumulate计算累加和
accumulated = itertools.accumulate(numbers)
# 打印累加结果
for total in accumulated:
print(total) # 输出:1 3 6 10 15
如果你提供了一个func
参数,它将用作二元操作符来计算累加值。
itertools.groupby(iterable, key=None)
itertools.groupby
函数将迭代器中的连续元素分组,这些元素具有相同的key
函数返回值。它返回一个迭代器,生成由组键和组迭代器组成的元组。
重要的是要注意,为了groupby
能够正确工作,输入迭代器iterable
中的元素必须是已排序的,因为groupby
只检查连续的元素是否相同。
示例:
import itertools
# 生成一个已排序的字符迭代器
characters = 'aaabbcc'
# 使用groupby按字符分组
grouped = itertools.groupby(characters)
# 打印分组结果
for key, group in grouped:
print(key, list(group)) # 输出:a ['a', 'a', 'a'] b ['b', 'b'] c ['c', 'c']
在这个例子中,字符按照它们在字符串中出现的顺序被分组。由于字符串是已排序的,所以groupby
能够正确地将连续的相同字符分为一组。
累加和分组迭代器提供了处理序列数据的有力工具,能够轻松地计算累加结果或对数据进行分组操作。需要注意的是,使用groupby
时需要确保数据已排序,否则结果可能不正确。
十、datetime
首先需要说明的是,相关的库还有time
这个库的功能更加全面,但也比较底层一些,这个也是必须要学习的,这里限于篇幅,仅介绍datetime。
10.1 基本介绍
Python中的datetime
标准库是一个强大且灵活的工具,它用于处理日期和时间相关的各种操作。通过这个库,我们可以方便地创建日期和时间对象,进行时间的计算,以及将时间格式化为我们需要的格式。
首先,datetime
库允许我们创建表示具体日期和时间的对象。这些对象可以包含年、月、日、时、分、秒、微秒等信息,让我们能够精确地表示某一时刻。
其次,datetime
库提供了丰富的功能,用于对时间进行各种计算。比如,我们可以计算两个日期之间的差值,得到它们之间相差的天数、小时数等。我们也可以给某个日期加上或减去一定的时间量,从而得到新的日期。
此外,datetime
库还支持将日期和时间对象转换为字符串,以及将字符串解析为日期和时间对象。这使得我们可以轻松地将时间数据保存到文件或数据库中,或者从文件或数据库中读取时间数据。
最后,datetime
库还提供了时区相关的功能,使得我们可以处理跨时区的时间问题。比如,我们可以将一个时区的时间转换为另一个时区的时间,这对于处理国际事务或者分布式系统的时间同步非常有用。
总的来说,datetime
库是Python中处理日期和时间的重要工具,它让我们能够方便地创建、计算和格式化时间数据,极大地简化了与时间相关的编程任务。如果你需要处理与时间相关的问题,无论是简单的日期计算,还是复杂的时区转换,datetime
库都能为你提供强大的支持。
10.2 datetime 的使用方法
10.2.1 时间计算
在Python的datetime
模块中,时间计算是一个非常重要的功能,它允许我们对日期和时间对象执行各种算术运算。下面我们将介绍与时间计算相关的几个关键方法。
timedelta
类
timedelta
类表示两个日期或时间之间的差异,常用于计算时间间隔。它可以通过多种方式创建,包括直接使用天数、秒数、微秒数等参数。
示例:
from datetime import timedelta
# 创建一个表示3天时间间隔的timedelta对象
delta = timedelta(days=3)
# 使用timedelta对象对日期进行加法运算
current_date = datetime.date.today()
new_date = current_date + delta
print(new_date) # 输出:当前日期加上3天后的日期
除了基本的加法运算,timedelta
对象还支持减法、乘法等运算,以及比较操作。
date
和datetime
对象的算术运算
date
和datetime
对象可以与timedelta
对象进行加法或减法运算,从而得到新的日期或时间对象。
示例:
from datetime import date, datetime, timedelta
# 创建一个date对象
today = date.today()
# 创建一个timedelta对象
one_week = timedelta(weeks=1)
# 计算一周后的日期
next_week = today + one_week
print(next_week) # 输出:一周后的日期
# 创建一个datetime对象
now = datetime.now()
# 计算一小时后的时间
one_hour_later = now + timedelta(hours=1)
print(one_hour_later) # 输出:当前时间加上1小时后的时间
时间比较
date
和datetime
对象还支持比较操作,例如等于(==)、不等于(!=)、大于(>)、小于(<)、大于等于(>=)和小于等于(<=)。
示例:
from datetime import date
# 创建两个date对象
date1 = date(2023, 1, 1)
date2 = date(2023, 1, 15)
# 比较两个日期
if date1 < date2:
print("date1早于date2") # 输出:date1早于date2
这些时间计算功能使得在Python中处理日期和时间变得非常灵活和方便。通过使用timedelta
以及date
和datetime
对象的算术运算,我们可以轻松地执行各种时间相关的计算任务。
10.2.2 时间和字符串转换
在Python的datetime
模块中,处理日期、时间对象和字符串之间的转换是非常常见的任务。这些转换允许我们将日期和时间信息以人类可读的格式存储或显示,同时也可以在程序中以结构化的方式使用这些信息。下面我们将介绍一些用于时间和字符串转换的关键方法。
strftime
方法
strftime
是date
、time
和datetime
对象的一个方法,用于将日期或时间对象格式化为字符串。它接受一个格式字符串作为参数,该字符串指定了日期或时间的输出格式。
示例:
from datetime import datetime
# 创建一个datetime对象
now = datetime.now()
# 使用strftime将datetime对象转换为字符串
formatted_time = now.strftime("%Y-%m-%d %H:%M:%S")
print(formatted_time) # 输出:类似"2023-03-15 14:30:00"的字符串
在上面的示例中,%Y
、%m
、%d
、%H
、%M
和%S
是格式代码,分别代表四位数的年份、两位数的月份、两位数的日期、24小时制的小时、分钟和秒。strftime
方法根据这些格式代码将日期时间对象转换为字符串。
strptime
方法
与strftime
相反,strptime
方法用于将字符串解析为date
、time
或datetime
对象。它也接受一个格式字符串,但这次是用来指定输入字符串的格式。
示例:
from datetime import datetime
# 定义一个日期时间字符串
date_string = "2023-03-15 14:30:00"
# 使用strptime将字符串解析为datetime对象
parsed_datetime = datetime.strptime(date_string, "%Y-%m-%d %H:%M:%S")
print(parsed_datetime) # 输出:类似datetime.datetime(2023, 3, 15, 14, 30)的对象
在这个例子中,我们使用与上面strftime
示例中相同的格式代码来告诉strptime
如何解析输入字符串。解析后的对象是一个datetime
对象,可以像其他日期时间对象一样使用。
date.fromisoformat
和datetime.fromisoformat
方法
对于符合ISO 8601格式的日期和时间字符串,可以使用date.fromisoformat
和datetime.fromisoformat
方法直接进行解析,无需指定格式字符串。
示例:
from datetime import date, datetime
# ISO 8601格式的日期字符串
iso_date_string = "2023-03-15"
iso_datetime_string = "2023-03-15T14:30:00"
# 使用fromisoformat方法解析日期字符串
parsed_date = date.fromisoformat(iso_date_string)
print(parsed_date) # 输出:类似date(2023, 3, 15)的对象
# 使用fromisoformat方法解析日期时间字符串
parsed_datetime = datetime.fromisoformat(iso_datetime_string)
print(parsed_datetime) # 输出:类似datetime.datetime(2023, 3, 15, 14, 30)的对象
这些方法提供了灵活且强大的工具,用于在Python程序中处理日期、时间和字符串之间的转换。无论是将日期时间信息以字符串形式存储或展示,还是在程序中进行结构化处理,都可以方便地使用这些方法实现。
十一、urllib
和 http
11.1 基本介绍
Python中的标准库http
和urllib
都是与HTTP协议相关的工具库,用于在网络上进行数据的发送和接收。对于想要进行网络编程或者与Web服务交互的开发者来说,这两个库是非常有用的。
首先,http
库提供了对HTTP协议底层的访问和操作。它允许你创建HTTP请求,设置请求头,发送请求到服务器,并接收来自服务器的响应。通过这个库,你可以更深入地控制HTTP通信的各个环节,比如自定义请求方法、处理重定向、管理连接池等。虽然http
库提供了底层的操作,但对于许多常见的网络请求,直接使用它可能会比较繁琐。
而urllib
库则是一个更高级别的网络编程接口,它简化了网络请求的操作,使得开发者能够更方便地发送HTTP请求和接收响应。urllib
库提供了几个模块,如urllib.request
用于发起网络请求,urllib.parse
用于解析URL,urllib.error
用于处理网络请求中可能出现的异常。使用urllib
库,你可以轻松地发起GET或POST请求,附带参数或数据,处理Cookie,甚至处理HTTPS请求。
总的来说,http
库提供了对HTTP协议的底层访问和操作,而urllib
库则提供了一个更高级别的接口,简化了网络编程的操作。如果你需要更精细地控制HTTP通信的各个环节,可以使用http
库;而如果你只是想简单地发送和接收HTTP请求,那么urllib
库会是一个更好的选择。这两个库的存在,使得Python在网络编程方面变得更加灵活和强大。
11.2 http的使用方法
http
库是Python标准库中的一个模块,它提供了HTTP客户端和服务器的基本功能。这个库允许你发送HTTP请求、接收HTTP响应,并构建HTTP服务器。接下来,我们将分模块来介绍http
库中的关键内容。
11.2.1 HTTP客户端
http
库中的client
模块提供了用于创建HTTP客户端的工具。这些客户端可以用来发送HTTP请求并接收响应。
1. HTTPConnection类
HTTPConnection
类是创建HTTP连接的基础。它允许你与指定的主机和端口建立连接,并发送HTTP请求。
示例:
import http.client
# 创建一个HTTP连接
conn = http.client.HTTPConnection("www.example.com")
# 发送GET请求
conn.request("GET", "/")
# 获取响应
response = conn.getresponse()
print(response.status, response.reason)
# 关闭连接
conn.close()
2. HTTPSConnection类
对于HTTPS连接,可以使用HTTPSConnection
类,它类似于HTTPConnection
,但提供了加密的通信。
11.2.2 HTTP服务器
http
库中的server
模块允许你构建简单的HTTP服务器。
1. BaseHTTPRequestHandler类
BaseHTTPRequestHandler
是一个用于处理HTTP请求的基础类。你可以通过继承这个类并重写相应的方法来处理不同的HTTP请求和生成响应。
示例:
from http.server import BaseHTTPRequestHandler, HTTPServer
class MyHandler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
self.wfile.write(b"Hello, World!")
# 创建HTTP服务器
server_address = ('', 8000)
httpd = HTTPServer(server_address, MyHandler)
print("Starting server...")
httpd.serve_forever()
在这个例子中,我们定义了一个自定义的处理器MyHandler
,并重写了do_GET
方法来处理GET请求。然后,我们创建了一个HTTP服务器实例,并指定了服务器的地址和处理器类。最后,调用serve_forever()
方法使服务器开始监听并处理请求。
11.2.3 HTTP状态码和响应头
http
库中的HTTPStatus
枚举类提供了HTTP状态码的常量定义,你可以使用这些常量来表示HTTP响应的状态。同时,在处理HTTP响应时,你可以通过响应对象的status
、reason
和getheader()
等方法来获取状态码、状态消息和响应头信息。
11.2.4 URL处理
虽然http
库本身不直接提供URL处理的工具,但通常与urllib
库结合使用来处理URL。urllib
库提供了用于解析、构建和操作URL的功能。
这只是对http
库的一个简单介绍,实际上这个库还提供了更多高级功能和选项,可以根据具体需求进一步探索和使用。需要注意的是,对于更复杂的HTTP客户端和服务器需求,通常会使用像requests
和flask
这样的第三方库,它们提供了更强大和灵活的功能。
11.3 urllib的使用方法
11.3.1 HTTP请求模块
urllib.request模块是Python中用于发送HTTP请求和处理HTTP响应的模块。它提供了许多有用的方法和类,可以方便地发送各种类型的HTTP请求,包括GET、POST等。
以下是urllib.request
模块中的一些重要方法和类的介绍:
- urlopen(url, data=None, [timeout, ]*[, cafile[, capath[, cadefault[, context]]])
urlopen
是urllib.request
模块中最常用的函数之一。它用于打开一个URL,并返回一个类文件对象,可以像操作文件一样读取HTTP响应的内容。
url
:要打开的URL地址。data
:可选参数,如果要发送POST请求,可以将请求体作为此参数传入。timeout
:可选参数,设置请求超时时间。
示例:
import urllib.request
response = urllib.request.urlopen('http://www.example.com')
html = response.read() # 读取响应内容
- Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None)
Request
类用于创建更复杂的HTTP请求。通过Request
对象,你可以设置请求头、请求方法(如GET、POST等)以及其他参数。
url
:请求的URL地址。data
:可选参数,请求体数据。headers
:可选参数,一个字典,包含自定义的请求头。method
:可选参数,HTTP请求方法,默认为’GET’。
示例:
import urllib.request
from urllib.parse import urlencode
url = 'http://www.example.com/search'
data = {'q': 'python', 'page': 10}
data = urlencode(data).encode('utf-8') # 将数据编码为字节串
req = urllib.request.Request(url, data, method='POST')
response = urllib.request.urlopen(req)
- install_opener(opener)
install_opener
函数用于安装一个全局的URL打开器。这在你需要自定义请求处理过程时非常有用,比如添加代理、处理cookies等。
opener
:一个实现了OpenerDirector
接口的实例,通常是一个urllib.request.build_opener
函数返回的打开器。
示例:
import urllib.request
# 创建一个自定义的打开器,比如添加代理
proxy_handler = urllib.request.ProxyHandler({'http': 'http://proxy.example.com:8080/'})
opener = urllib.request.build_opener(proxy_handler)
# 安装自定义的打开器
urllib.request.install_opener(opener)
# 现在,所有的urlopen调用都会使用这个代理
response = urllib.request.urlopen('http://www.example.com')
- build_opener([handler, …])
build_opener
函数用于创建一个新的OpenerDirector
实例,可以通过传入一个或多个处理器来定制HTTP请求的处理过程。
handler
:可选参数,一个或多个处理器实例。
使用build_opener
,你可以添加各种处理器来定制请求,比如ProxyHandler
用于设置代理,HTTPCookieProcessor
用于处理cookies等。
这些只是urllib.request
模块中的一部分重要方法和类。通过合理使用这些方法和类,你可以轻松地在Python中发送HTTP请求并处理响应。更多详细信息和示例,请参考官方文档:https://docs.python.org/3/library/urllib.request.html#module-urllib.request。
11.3.2 工具模块
urllib.parse模块是Python的内置库,用于解析URLs并对URL的各部分进行操作。它提供了许多实用的函数和类,使得处理URLs变得简单且高效。
以下是一些urllib.parse
模块中常用的方法和类的介绍:
- urlparse(urlstring, scheme=‘’, allow_fragments=True)
urlparse
函数用于将URL字符串解析为6个组件,这些组件分别是scheme(协议)、netloc(网络位置)、path(路径)、params(参数)、query(查询参数)和fragment(片段)。返回一个包含这些组件的ParseResult
对象。
示例:
from urllib.parse import urlparse
url = 'http://www.example.com/path?name=value#fragment'
parsed_url = urlparse(url)
print(parsed_url.scheme) # 输出: http
print(parsed_url.netloc) # 输出: www.example.com
print(parsed_url.path) # 输出: /path
print(parsed_url.params) # 输出: 空字符串
print(parsed_url.query) # 输出: name=value
print(parsed_url.fragment) # 输出: fragment
- urlunparse(parts)
urlunparse
函数与urlparse
相反,它接受一个ParseResult
对象或是一个包含6个URL组件的元组,并返回相应的URL字符串。
示例:
from urllib.parse import urlunparse, ParseResult
parts = ('http', 'www.example.com', '/path', '', 'name=value', 'fragment')
url = urlunparse(parts)
print(url) # 输出: http://www.example.com/path?name=value#fragment
- quote(string, safe=‘/’, encoding=‘utf-8’, errors=‘replace’)
quote
函数用于对URL中的特殊字符进行转义,使其符合URL的格式要求。safe
参数是一个字符串,其中的字符不会被转义。
示例:
from urllib.parse import quote
safe_chars = ',/;:?=+&-$#'
unsafe_string = "Hello, world! This is a test=1&test2=2"
quoted_string = quote(unsafe_string, safe=safe_chars)
print(quoted_string) # 输出: Hello%2C+world%21+This+is+a+test%3D1%26test2%3D2
- unquote(string, encoding=‘utf-8’, errors=‘replace’)
unquote
函数是quote
的反函数,用于对转义后的URL字符串进行解码。
示例:
from urllib.parse import unquote
quoted_string = "Hello%2C+world%21+This+is+a+test%3D1%26test2%3D2"
unquoted_string = unquote(quoted_string)
print(unquoted_string) # 输出: Hello, world! This is a test=1&test2=2
- urlencode(query, doseq=True, safe=‘’, encoding=‘utf-8’, errors=‘replace’, quote_via=quote)
urlencode
函数用于将字典形式的查询参数转换为适合放在URL查询字符串中的格式。
示例:
from urllib.parse import urlencode
params = {
'name': 'value',
'numbers': [1, 2, 3],
'multi': ['a', 'b']
}
encoded_params = urlencode(params)
print(encoded_params) # 输出: name=value&numbers=1&numbers=2&numbers=3&multi=a&multi=b
这些只是urllib.parse
模块中的一部分重要方法和类。通过合理组合使用这些方法,你可以轻松地解析、构建和转义URL,以适应各种网络编程需求。更多详细信息和示例,请参考官方文档:https://docs.python.org/3/library/urllib.parse.html#module-urllib.parse。
11.3.3 robotparser
非常抱歉,我误解了您的格式要求。以下是按照您提供的格式,对urllib.robotparser
模块中的重要方法进行介绍的内容:
urllib.robotparser模块
urllib.robotparser
是Python标准库中的一个模块,专门用于解析robots.txt文件,这些文件通常放置在网站的根目录下,用于指导网络爬虫(如搜索引擎的爬虫)如何访问网站内容。
模块中的主要类是RobotFileParser
,它提供了以下关键方法:
set_url(url)
此方法用于设置robots.txt文件的URL地址。
示例:
import urllib.robotparser
rp = urllib.robotparser.RobotFileParser()
rp.set_url("http://www.example.com/robots.txt")
read()
调用此方法会从之前通过set_url
设置的URL中读取robots.txt文件,并解析其内容。
示例:
rp.read()
can_fetch(useragent, url)
此方法用于判断特定的用户代理(useragent)是否有权限抓取指定的URL。如果有权限,则返回True;否则返回False。
示例:
can_crawl = rp.can_fetch("Googlebot", "/some/path")
print(can_crawl) # 输出True或False
mtime()
此方法返回robots.txt文件的最后修改时间。如果文件尚未被读取或无法获取修改时间,则返回None。
示例:
last_modified = rp.mtime()
print(last_modified) # 输出文件的最后修改时间,或者None
modified()
与mtime()
方法类似,此方法也返回robots.txt文件的最后修改时间,但返回的是一个时间戳(即Unix时间戳)。如果文件尚未被读取或无法获取修改时间,则返回None。
示例:
timestamp = rp.modified()
print(timestamp) # 输出文件最后修改时间的时间戳,或者None
这些方法是urllib.robotparser
模块中RobotFileParser
类的核心功能,它们使得开发者能够方便地解析robots.txt文件,并根据其内容来决定爬虫的行为。然而,需要注意的是,robots.txt文件只是建议性的,爬虫可以选择遵守或忽略这些规则。
十二、logging
12.1 基本介绍
logging
是Python中的一个标准库,它用于记录程序运行时的各种信息,帮助开发者更好地理解和调试程序。无论是普通的日志记录,还是错误追踪,logging
库都能提供强大的支持。
这个库的主要功能可以分为以下几部分:
1. 日志级别管理
logging
库允许你设置不同的日志级别,如DEBUG、INFO、WARNING、ERROR和CRITICAL。这些级别可以帮助你过滤和识别不同重要程度的日志信息。例如,当你只想看到程序中的错误时,你可以将日志级别设置为ERROR,这样只有错误级别的日志才会被记录下来。
2. 日志输出格式和目的地
你可以自定义日志的输出格式,比如包括时间戳、日志级别、消息内容等。此外,logging
库还支持将日志输出到不同的目的地,如控制台、文件、甚至是远程服务器。这样,你可以根据实际需求选择最合适的日志记录方式。
3. 日志处理器
logging
库中的日志处理器(handler)负责将日志信息发送到指定的目的地。你可以添加多个处理器,以便将日志信息同时输出到多个地方。例如,你可以将日志同时记录到文件和控制台,方便查看和调试。
总的来说,logging
库通过提供灵活的日志级别、输出格式和目的地、以及强大的日志处理器和记录器,帮助开发者有效地管理和分析程序的日志信息。无论是对于日常的程序调试,还是对于大规模系统的监控和预警,logging
库都是一个不可或缺的工具。
12.2 logging的使用方法
12.2.1 日志级别管理
日志级别管理在Python的logging
模块中是一个关键概念,它允许开发者控制记录哪些严重程度的消息。通过合理地设置日志级别,可以过滤掉不重要的信息,只保留关键或错误的信息,从而简化日志查看和分析的过程。
Python的logging
模块定义了以下几个标准的日志级别(从低到高):
- DEBUG:详细的信息,通常只在诊断问题时才需要。
- INFO:确认一切按预期运行。
- WARNING:表明某些预期之外的事情发生,或即将发生,但软件仍能按预期工作。
- ERROR:由于更严重的问题,软件已不能执行某些功能。
- CRITICAL:严重错误,通常这意味着程序本身可能无法继续运行。
这些日志级别可以通过logging.setLevel()
方法设置,从而控制记录哪些级别的日志。例如:
import logging
# 设置日志级别为WARNING,这样只有WARNING及以上级别的日志会被记录
logging.basicConfig(level=logging.WARNING)
logging.debug('这是一条debug级别的日志') # 不会被记录
logging.info('这是一条info级别的日志') # 不会被记录
logging.warning('这是一条warning级别的日志') # 会被记录
logging.error('这是一条error级别的日志') # 会被记录
logging.critical('这是一条critical级别的日志') # 会被记录
在上面的例子中,由于我们设置的日志级别是WARNING
,所以只有WARNING
、ERROR
和CRITICAL
级别的日志会被记录下来。DEBUG
和INFO
级别的日志会被忽略。
此外,每个logger也可以单独设置其日志级别,这使得开发者能够更精细地控制不同部分的日志输出。例如:
# 创建一个logger并设置其级别为INFO
logger = logging.getLogger('my_logger')
logger.setLevel(logging.INFO)
# 使用这个logger记录日志
logger.debug('这条debug日志不会被记录,因为logger的级别是INFO')
logger.info('这条info日志会被记录')
通过合理地设置日志级别,开发者可以有效地管理日志信息,使其既不会过于冗长难以查看,也不会因为缺少关键信息而难以诊断问题。
12.2.2 日志输出格式和目的地
在Python的logging
库中,日志输出格式和目的地是两个重要的概念,它们可以帮助我们更好地管理和查看日志信息。
日志输出格式
logging
库允许我们自定义日志的输出格式。这主要通过Formatter
类实现,它定义了日志输出的具体格式。使用Formatter
时,我们可以指定一个格式字符串,其中可以包含各种占位符,用于表示日志记录中的不同部分,如时间、级别、消息等。
例如,下面的代码创建了一个Formatter
对象,用于将日志时间、级别和消息输出到控制台:
import logging
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
在这里,%(asctime)s
会被替换为日志事件发生的时间,%(levelname)s
会被替换为日志级别(如DEBUG、INFO等),%(message)s
则会被替换为实际的日志消息。
日志目的地
日志的目的地决定了日志信息应该被发送到哪里。logging
库支持多种目的地,包括但不限于控制台、文件、电子邮件、甚至是网络服务器。这些目的地通过Handler
类实现。
例如,要将日志信息输出到文件,我们可以使用FileHandler
:
import logging
# 创建一个logger
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
# 创建一个handler,用于写入日志文件
fh = logging.FileHandler('app.log')
# 再创建一个handler,用于输出到控制台
ch = logging.StreamHandler()
# 定义handler的输出格式
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh.setFormatter(formatter)
ch.setFormatter(formatter)
# 给logger添加handler
logger.addHandler(fh)
logger.addHandler(ch)
在上面的代码中,我们创建了一个FileHandler
,它将日志信息写入名为app.log
的文件中。同时,我们还创建了一个StreamHandler
,它将日志信息输出到控制台。这样,日志信息就可以同时出现在文件和控制台上。
通过使用Formatter
和Handler
,我们可以灵活地定制日志的输出格式和目的地,以适应不同的需求。无论是简单的调试信息输出,还是复杂的系统日志记录,logging
库都能提供强大的支持。
12.2.3 日志处理器
日志处理器(Handlers)在Python的logging
库中扮演着重要的角色。它们负责确定如何将日志消息分发给指定的目标。换句话说,Handlers定义了日志信息的“输出方式”。以下是关于日志处理器的一些关键知识:
基础日志处理器
- StreamHandler:这个处理器将日志消息输出到指定的流,通常是标准输出(sys.stdout)或标准错误(sys.stderr)。它是非常基础的处理器,用于在控制台直接查看日志信息。
import logging
# 创建一个handler,用于写入标准输出
ch = logging.StreamHandler()
- FileHandler:这个处理器将日志消息写入到指定的文件中。通过FileHandler,你可以将日志持久化保存到磁盘上,便于后续的分析和查看。
import logging
# 创建一个handler,用于写入日志文件
fh = logging.FileHandler('app.log')
高级日志处理器
除了上述的基础处理器,logging
库还提供了其他一些高级处理器,它们具有更复杂的特性:
- RotatingFileHandler:这个处理器允许日志文件按照大小或时间进行滚动。例如,你可以设置它每达到一定大小或每天创建新的日志文件,而旧文件则会被重命名或删除。
import logging
from logging.handlers import RotatingFileHandler
# 创建一个handler,用于写入滚动日志文件
rfh = RotatingFileHandler('app.log', maxBytes=1024*1024, backupCount=5)
- TimedRotatingFileHandler:这个处理器根据时间间隔来滚动日志文件,如每天、每周或每月。
import logging
from logging.handlers import TimedRotatingFileHandler
# 创建一个handler,用于每天滚动日志文件
trfh = TimedRotatingFileHandler('app.log', when='D', interval=1, backupCount=7)
-
SocketHandler:这个处理器将日志消息发送到网络套接字,允许远程日志记录。
-
SMTPHandler:这个处理器通过电子邮件发送日志消息,通常用于在发生严重错误时发送警报。
-
MemoryHandler:这个处理器将日志消息首先存储在内存中,当达到某个条件(如大小或记录数)时,再将消息传递给另一个处理器。
使用日志处理器
要使用这些处理器,你需要设置它们的一些属性,如日志级别和格式,然后将它们添加到Logger对象中。这样,当Logger记录消息时,就会通过这些处理器来分发。
import logging
# 创建一个logger
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
# 创建一个handler,设置其级别和格式
handler = logging.FileHandler('app.log')
handler.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
# 给logger添加handler
logger.addHandler(handler)
日志处理器是logging
库中非常灵活且强大的组件,通过合理地选择和配置它们,你可以满足各种复杂的日志记录需求。
十三、argparse
13.1 基本介绍
argparse
是 Python 标准库中的一个非常实用的模块,用于编写命令行接口。它的存在主要是为了简化开发者编写能够处理复杂命令行选项和参数的程序的过程。对于用户来说,这意味着他们可以通过命令行以更直观、更灵活的方式与程序进行交互。
主要功能概括:
-
定义命令行参数:
argparse
允许开发者定义程序应该接受的命令行参数,包括它们的名称、类型、是否必需等。 -
解析命令行输入:当程序运行时,
argparse
会自动解析用户输入的命令行参数,并将它们转换为 Python 数据结构(如字典或对象),方便开发者在程序中使用。 -
生成帮助文档:
argparse
可以自动生成命令行工具的帮助文档,用户可以通过输入特定的命令(如--help
)来查看这些文档,了解如何正确使用程序。 -
错误处理:如果用户提供了无效或不正确的命令行参数,
argparse
会负责捕获这些错误,并以友好的方式向用户显示错误信息。
13.2 argparse的使用方法
argparse
是 Python 的一个标准库,用于从命令行解析参数和选项。它提供了一种简单的方式来编写用户友好的命令行接口。通过 argparse
,你可以定义程序需要哪些命令行参数,然后 argparse
会自动从命令行中解析这些参数,并将它们转换为 Python 数据类型。
创建 ArgumentParser 对象
使用 argparse
的第一步是创建一个 ArgumentParser
对象。这个对象包含了所有关于如何解析命令行参数的信息。
import argparse
parser = argparse.ArgumentParser(description='这是一个示例程序')
添加参数
接下来,你可以使用 add_argument
方法向 ArgumentParser
对象添加命令行参数。这个方法可以指定参数的名字、是否需要命令行提供值、值的类型等。
parser.add_argument('--input', type=str, help='输入文件的路径')
parser.add_argument('--output', type=str, help='输出文件的路径')
parser.add_argument('--verbose', action='store_true', help='是否启用详细输出')
在上面的例子中,我们添加了三个参数:--input
和 --output
需要命令行提供一个字符串值;--verbose
是一个标志,不需要值,当提供这个标志时,其对应的 action
会将 verbose
属性设置为 True
。
解析参数
一旦定义了所有的参数,你就可以使用 parse_args
方法来解析命令行参数。这将返回一个包含所有解析后参数的对象。
args = parser.parse_args()
解析后,你可以通过 args
对象来访问命令行参数的值。例如,args.input
将包含 --input
参数的值(如果存在的话)。
使用示例
假设你有一个脚本 my_script.py
,它使用 argparse
来解析命令行参数:
import argparse
parser = argparse.ArgumentParser(description='处理输入并生成输出')
parser.add_argument('--input', type=str, required=True, help='输入文件的路径')
parser.add_argument('--output', type=str, required=True, help='输出文件的路径')
args = parser.parse_args()
print(f'输入文件: {args.input}')
print(f'输出文件: {args.output}')
在命令行中运行这个脚本并传递参数:
python my_script.py --input data.txt --output output.txt
输出将会是:
输入文件: data.txt
输出文件: output.txt
错误处理和帮助信息
如果用户提供了无效的参数或缺少必需的参数,argparse
会自动打印错误消息并退出程序。此外,你还可以通过 -h
或 --help
参数来让 argparse
打印出所有可用的选项和它们的描述,这对于用户来说非常有用。
argparse
是一个强大且灵活的工具,可以帮助你编写清晰、用户友好的命令行接口。通过仔细定义参数和选项,你可以让你的程序更加易于使用和理解。
十四、csv
14.1 基本介绍
csv
是 Python 的一个内置标准库,它用于读写逗号分隔值(Comma-Separated Values)文件,通常简称为 CSV 文件。CSV 文件是一种常见的数据交换格式,它可以用任何文本编辑器打开和编辑,并且可以被许多电子表格软件和编程语言所支持。
csv库存在的意义:
CSV 文件格式简单、易读且易于处理,因此经常被用于在不同程序和系统之间交换数据。csv
库的存在使得 Python 程序员能够轻松地从 CSV 文件中读取数据,或者将数据写入 CSV 文件,从而方便地进行数据分析和处理。
csv库的主要功能:
csv
库的主要功能可以分为两部分:读取 CSV 文件和写入 CSV 文件。
-
读取 CSV 文件
csv
库提供了读取 CSV 文件的功能,将文件中的数据解析成 Python 可以处理的数据结构,如列表或字典。通过这个功能,我们可以方便地读取 CSV 文件中的数据,进行进一步的分析和处理。 -
写入 CSV 文件
除了读取 CSV 文件外,
csv
库还提供了将 Python 数据结构写入 CSV 文件的功能。这意味着我们可以将处理后的数据,或者生成的新数据,以 CSV 格式保存到文件中,方便与其他程序或系统进行数据交换。
总结:
csv
库是 Python 中用于处理 CSV 文件的一个强大工具。它使得我们可以轻松地从 CSV 文件中读取数据,或者将数据写入 CSV 文件,从而方便地进行数据交换和处理。无论是数据分析、机器学习还是其他需要处理大量数据的场景,csv
库都是一个不可或缺的工具。
14.2 使用方法
Python的csv
模块提供了一种方便的方式来读取和写入CSV(逗号分隔值)文件,这是一种常见的数据交换格式。CSV文件由任意数量的记录组成,记录之间以某种换行符分隔(通常为换行符或回车符),每条记录由字段组成,字段间的分隔符是其他字符或字符串,最常见的是逗号或制表符。
读取CSV文件
要读取CSV文件,可以使用csv.reader
对象。以下是一个简单的示例:
import csv
with open('example.csv', 'r', newline='') as csvfile:
reader = csv.reader(csvfile)
for row in reader:
print(row)
在这个例子中,csv.reader
创建了一个读取器对象,它遍历CSV文件的每一行,将每行解析为一个字符串列表。newline=''
参数用于避免在Windows系统中出现额外的空行。
写入CSV文件
要写入CSV文件,可以使用csv.writer
对象。以下是一个简单的示例:
import csv
# 要写入CSV文件的数据
data = [
['Name', 'Age', 'City'],
['Alice', '25', 'New York'],
['Bob', '30', 'San Francisco'],
]
with open('output.csv', 'w', newline='') as csvfile:
writer = csv.writer(csvfile)
writer.writerows(data)
在这个例子中,csv.writer
创建了一个写入器对象,它接受一个二维列表(或任何可迭代对象的迭代器),并将每一行写入CSV文件。writerows
方法用于写入多行数据。
csv.DictReader和csv.DictWriter
除了基本的读写操作,csv
模块还提供了csv.DictReader
和csv.DictWriter
类,它们分别用于以字典的形式读取和写入CSV数据。这在处理包含列名的CSV文件时非常有用。
csv.DictReader示例:
import csv
with open('example.csv', 'r', newline='') as csvfile:
reader = csv.DictReader(csvfile)
for row in reader:
print(row['Name'], row['Age'])
在这个例子中,每一行数据被解析为一个字典,其中键是列名,值是对应的数据。
csv.DictWriter示例:
import csv
fieldnames = ['Name', 'Age']
data = [
{'Name': 'Alice', 'Age': '25'},
{'Name': 'Bob', 'Age': '30'},
]
with open('output.csv', 'w', newline='') as csvfile:
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader() # 写入列名
writer.writerows(data) # 写入数据行
在这个例子中,我们首先定义了列名(fieldnames
),然后创建了一个字典列表(data
),每个字典代表一行数据。csv.DictWriter
用于将数据以CSV格式写入文件,writeheader
方法用于写入列名作为文件的第一行。
这些只是csv
模块提供的一些基本功能。它还有其他高级用法,比如自定义字段的分隔符、引号字符等,可以通过查看官方文档来了解更多详情。
十五、socket
15.1 基本介绍
socket
是 Python 的一个内置标准库,它提供了创建和操作网络套接字的接口。套接字是网络编程的基石,它们允许不同计算机上的应用程序进行通信。通过使用 socket
库,Python 程序员可以轻松地编写网络应用程序,如客户端、服务器、聊天工具等。
socket库存在的意义:
网络编程在现代软件开发中占据着重要的地位,它使得不同计算机上的程序能够互相交换信息、共享资源。socket
库的存在,让 Python 程序员能够直接利用底层网络协议,进行高效、灵活的网络通信。它简化了网络编程的复杂性,使得开发者能够更专注于业务逻辑的实现。
socket库的主要功能:
socket
库的主要功能可以分为以下几个方面:
-
创建套接字:
socket
库允许程序员创建不同类型的套接字,如 TCP 套接字和 UDP 套接字。这些套接字是网络通信的基本单元,它们负责在发送和接收数据时进行必要的封装和解封装。 -
绑定地址和端口:
创建套接字后,通常需要将其绑定到一个特定的地址(IP 地址)和端口号。这样,其他计算机上的程序就可以通过该地址和端口号与该套接字进行通信。 -
监听和接受连接:
对于服务器套接字,它们需要监听特定的端口,等待客户端的连接请求。一旦有客户端连接,服务器就可以接受该连接,并与其进行通信。 -
发送和接收数据:
通过套接字,程序可以发送和接收数据。这些数据可以是文本、二进制文件或其他类型的信息。发送和接收数据的具体方式取决于所使用的套接字类型(如 TCP 或 UDP)。 -
关闭套接字:
当通信完成时,需要关闭套接字以释放资源。socket
库提供了关闭套接字的方法,确保资源的正确释放。
15.2 socket的基本使用
Python的socket
库是网络通信的基础,它允许你创建套接字对象,这些对象可以用来与其他计算机进行通信。通过套接字,你可以发送和接收数据,实现各种网络应用,如Web服务器、客户端程序、聊天应用等。
创建套接字
创建套接字是使用socket
库的第一步。你可以使用socket()
函数来创建一个新的套接字对象。这个函数接受两个参数:地址族和套接字类型。
import socket
# 创建一个IPv4, TCP套接字
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
在上面的例子中,socket.AF_INET
表示使用IPv4地址族,socket.SOCK_STREAM
表示使用TCP协议。
绑定地址
一旦你创建了一个套接字,你可能想要将它绑定到一个特定的地址和端口上。这通常在使用服务器套接字时完成,以确保客户端知道如何连接到服务器。
# 绑定到本地地址和端口
s.bind(('localhost', 12345))
监听连接
对于服务器套接字,你还需要调用listen()
方法来开始监听传入的连接请求。
# 开始监听连接,最多允许5个连接排队
s.listen(5)
接受连接
服务器使用accept()
方法来接受一个传入的连接请求,并返回一个新的套接字对象,用于与该客户端进行通信。
# 接受一个连接请求
client_socket, addr = s.accept()
print(f"Connection from {addr} has been established!")
发送和接收数据
使用套接字发送和接收数据通常涉及send()
和recv()
方法(对于TCP套接字)或sendto()
和recvfrom()
方法(对于UDP套接字)。
# 发送数据
s.send(b'Hello, world!')
# 接收数据,通常需要指定一个缓冲区大小
data = s.recv(1024)
关闭套接字
完成通信后,应使用close()
方法来关闭套接字。
# 关闭套接字
s.close()
错误处理
网络通信经常涉及错误和异常处理。socket
库定义了一系列异常,如socket.error
,用于处理网络错误。
其他重要方法和属性
getsockname()
:返回套接字自己的地址。getpeername()
:返回连接对端的地址(仅适用于已连接的套接字)。setsockopt()
和getsockopt()
:用于设置和获取套接字的选项。settimeout()
和gettimeout()
:用于设置和获取套接字的超时时间。
这只是socket
库的基础知识。实际上,网络通信涉及的内容远比这复杂,包括处理并发连接、异步IO、加密等。但socket
库为你提供了基础工具,让你能够构建出强大的网络应用。
十六、xml
和 html
16.1 基本介绍
在Python中,xml
和 html
是两个重要的标准库,它们分别用于处理XML和HTML数据。下面我将对这两个库进行概括性的介绍,尽量做到通俗易懂。
xml库
XML(可扩展标记语言)是一种用于编码文档的标记语言,它既可以作为数据的存储格式,也可以作为数据的传输格式。Python的xml
库提供了对XML文档的解析和创建功能。
xml
库的主要功能可以分为以下几部分:
-
解析XML:
xml
库可以读取XML文件或字符串,并将其解析成Python对象,如ElementTree对象或DOM对象。这样,你就可以在Python中方便地访问和操作XML数据了。 -
创建XML:除了解析XML,
xml
库还允许你创建新的XML文档。你可以使用库中的类和方法来构建XML树结构,然后将其序列化为字符串或保存到文件中。 -
验证XML:
xml
库还可以用于验证XML文档是否符合特定的XML Schema或DTD(文档类型定义)。这有助于确保XML数据的准确性和一致性。
html库
HTML(超文本标记语言)是用于创建网页的标准标记语言。Python的html
库提供了一些实用的函数和类,用于处理HTML数据。
html
库的主要功能可以分为以下几部分:
-
解析HTML:虽然
html
库本身并不直接提供HTML解析功能,但它可以与其他库(如BeautifulSoup
)一起使用,以解析HTML文档并提取其中的信息。这使得在Python中处理HTML数据变得更加容易。 -
转义HTML:
html
库提供了一些函数,用于将特殊字符转换为HTML实体,以防止在HTML文档中出现语法错误或安全漏洞。这对于生成安全的HTML内容非常有用。 -
生成HTML:虽然
html
库本身并不直接提供生成完整HTML文档的功能,但它提供了一些函数和类,可以帮助你生成HTML片段或特定的HTML元素。这些功能对于在Python中动态生成HTML内容非常有用。
16.2 xml的基本使用
在Python中,xml
库提供了丰富的工具和模块,用于处理XML数据。XML(可扩展标记语言)是一种标记语言,用于定义数据的结构和内容,使得数据既可以被人类阅读,也可以被机器解析。
关键模块
- xml.etree.ElementTree
xml.etree.ElementTree
(通常简称为ET
)是Python标准库中的一个轻量级且高效的模块,用于解析和创建XML文档。
重要方法
-
parse(source)
解析XML文档,返回一个ElementTree对象。source
可以是一个文件名或者文件对象。import xml.etree.ElementTree as ET tree = ET.parse('example.xml')
-
ElementTree.getroot()
返回ElementTree对象的根元素。root = tree.getroot()
-
SubElement(parent, tag)
为指定的父元素parent
创建一个子元素,并返回这个子元素。tag
是子元素的标签名。child = ET.SubElement(root, 'child_tag')
-
Element.find(tag)
和Element.findall(tag)
在元素中查找具有指定标签名的子元素。find
返回第一个匹配的元素,而findall
返回所有匹配的元素的列表。element = root.find('child_tag') elements = root.findall('child_tag')
-
Element.findtext(tag)
查找具有指定标签名的子元素,并返回该子元素的文本内容。text = root.findtext('child_tag')
-
Element.iter(tag)
迭代所有具有指定标签名的子元素。for elem in root.iter('child_tag'): print(elem.tag, elem.text)
-
Element.set(key, value)
和Element.get(key)
设置或获取元素的属性值。root.set('attribute', 'value') value = root.get('attribute')
-
ElementTree.write(file, encoding='us-ascii', xml_declaration=True, method='xml')
将ElementTree对象写入文件。tree.write('output.xml')
除了xml.etree.ElementTree
,Python的xml
库还提供了其他模块,如xml.dom
和xml.sax
,它们提供了不同的接口和方式来处理XML文档。选择使用哪个模块取决于特定的应用需求和个人的偏好。
安全性
当处理来自不受信任源的XML数据时,务必谨慎。恶意构造的XML数据可能导致安全问题,如XML注入攻击。因此,在使用Python的xml
库处理XML数据时,应确保验证和清理输入数据,以防止潜在的安全漏洞。
总的来说,Python的xml
库提供了一组强大的工具,使得解析、创建和操作XML数据变得相对简单和直观。
16.3 html的使用方法
Python的html
库提供了一系列与HTML处理相关的功能,使得在Python程序中解析、创建和操作HTML文档变得相对简单。以下是关于html
库中关键方法和相关知识的介绍:
html.entities
html.entities
模块提供了HTML实体与相应字符之间的映射。这在你需要将HTML实体转换为普通字符或将普通字符转换为HTML实体时非常有用。
html.escape(s)
html.escape
函数用于将字符串s
中的特殊字符转换为HTML实体。这有助于防止在HTML文档中插入不安全的代码。
示例:
import html
# 转义特殊字符
escaped_string = html.escape('<"&\'')
print(escaped_string) # 输出: <"&'
html.unescape(s)
html.unescape
函数与html.escape
相反,它将HTML实体转换回对应的字符。
示例:
import html
# 转换HTML实体回字符
unescaped_string = html.unescape('<"&'')
print(unescaped_string) # 输出: <"&\'
html.parser
html.parser
模块提供了一个简单的HTML解析器,它可以用来解析HTML文档并生成一个DOM树。这个模块非常适合那些只需要基本HTML解析功能的应用。
html.parser.HTMLParser
HTMLParser
是html.parser
模块中的一个类,它提供了HTML解析的功能。你可以通过继承HTMLParser
并重写其方法(如handle_starttag
, handle_endtag
, handle_data
等)来定义解析HTML文档时的行为。
示例:
from html.parser import HTMLParser
class MyHTMLParser(HTMLParser):
def handle_starttag(self, tag, attrs):
print(f"Start tag: {tag}")
def handle_endtag(self, tag):
print(f"End tag: {tag}")
def handle_data(self, data):
print(f"Data: {data}")
# 创建解析器实例并解析HTML文档
parser = MyHTMLParser()
parser.feed('<html><head><title>Test</title></head><body><h1>Parse me!</h1></body></html>')
上述代码定义了一个自定义的HTML解析器,它会在遇到开始标签、结束标签和数据时打印相应的信息。
安全性
当处理来自不受信任源的HTML数据时,需要格外小心,以防止跨站脚本攻击(XSS)。确保不要直接插入未经处理的用户输入到HTML文档中,而是使用像html.escape
这样的函数来转义特殊字符。
总的来说,Python的html
库提供了一套实用的工具,用于处理HTML文档中的特殊字符和解析HTML文档。通过这些工具,你可以更安全、更有效地在Python程序中操作HTML数据。
十七、hashlib
17.1 基本介绍
hashlib
是 Python 中的一个标准库,用于提供常见哈希算法的接口,包括 MD5、SHA1、SHA256 等。哈希算法能够将任意长度的数据转换为固定长度的哈希值,并且这个过程是不可逆的,也就是说,无法通过哈希值恢复原始数据。
hashlib库存在的意义:
哈希算法在信息安全领域有着广泛的应用。它们可以用于检验数据的完整性,验证消息是否被篡改,以及作为数字签名的基础等。通过使用 hashlib
,Python 程序员可以方便地计算数据的哈希值,从而确保数据的完整性和安全性。
hashlib库的主要功能:
hashlib
库的主要功能可以概括为以下几个部分:
-
哈希算法的选择:
hashlib
提供了多种哈希算法供用户选择,每种算法都有其特定的应用场景和安全级别。例如,MD5 和 SHA1 是较早的哈希算法,但由于已知的安全漏洞,它们现在主要用于非安全相关的场景。而 SHA256 和 SHA3 等更现代的算法则提供了更高的安全性。 -
哈希值的计算:
用户可以使用hashlib
库来计算数据的哈希值。这通常涉及将数据作为输入,调用相应的哈希算法,并获取生成的哈希值。这个哈希值是一个固定长度的字符串,用于表示原始数据的唯一标识。 -
哈希值的更新:
hashlib
还支持分块计算哈希值,这对于处理大文件或数据流非常有用。用户可以通过多次调用哈希对象的update()
方法来逐步添加数据,并在最后调用hexdigest()
或类似方法获取最终的哈希值。 -
哈希值的比较:
虽然hashlib
本身并不直接提供哈希值的比较功能,但用户可以通过比较两个哈希值字符串来检查两个数据块是否相同。由于哈希算法的特性,即使原始数据只有微小的差异,其哈希值也会有显著的不同。
17.2 hashlib的使用方法
hashlib
是 Python 的一个标准库,它提供了常见的哈希算法,如 MD5,SHA1,SHA256 等。哈希函数是一种将任意长度的数据映射为固定长度的数据的算法,常用于数据完整性校验、密码存储等场景。
关键方法
-
hashlib.new(name, data=b'')
此方法用于创建一个新的哈希对象。
name
参数指定了要使用的哈希算法的名称,如'md5'
,'sha1'
,'sha256'
等。data
参数是可选的,用于初始化哈希对象的数据。示例:
import hashlib md5_hash = hashlib.new('md5') sha256_hash = hashlib.new('sha256')
-
hash.update(arg)
此方法用于将数据添加到哈希对象中。你可以多次调用此方法以处理大量的数据,而无需一次性将所有数据加载到内存中。
示例:
md5_hash.update(b'Hello, world!')
-
hash.digest()
此方法返回哈希对象的二进制摘要。摘要的长度取决于所选的哈希算法。
示例:
md5_digest = md5_hash.digest()
-
hash.hexdigest()
此方法返回哈希对象的十六进制表示的摘要。它通常比
digest()
方法返回的二进制摘要更易读。示例:
md5_hexdigest = md5_hash.hexdigest() print(md5_hexdigest) # 输出类似 'acbd18db4cc2f85cedef654fccc4a4d8' 的十六进制字符串
安全性注意事项
- 一些哈希算法(如 MD5 和 SHA1)已经被认为不够安全,因为它们容易受到碰撞攻击。对于需要高安全性的应用,建议使用 SHA256 或更安全的算法。
- 永远不要使用哈希函数来存储密码,因为哈希函数不是单向的,它们可以被设计用来找到相同的输入。应该使用专门的密码哈希函数,如
bcrypt
,argon2
或scrypt
,它们加入了“盐值”和迭代次数,使得密码哈希更加安全。
示例
以下是一个使用 hashlib
计算字符串的 SHA256 哈希值的简单示例:
import hashlib
# 创建一个新的 SHA256 哈希对象
sha256_hash = hashlib.new('sha256')
# 更新哈希对象的数据
data = b'Hello, world!'
sha256_hash.update(data)
# 获取十六进制表示的摘要
sha256_hexdigest = sha256_hash.hexdigest()
# 打印结果
print(sha256_hexdigest) # 输出类似 'b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9' 的字符串
通过 hashlib
库,你可以方便地为数据生成哈希值,用于验证数据的完整性和一致性。