• Python3.11教程6:标准库简介1——os、shutil、sys、random、time、datetime、 threading


    参考:Python3.11官方教程《标准库简介》Python 标准库官方文档

      Python的标准库是Python编程语言提供的一组内置模块和函数,用于执行各种常见的任务和操作。这些模块和函数被广泛使用,它们提供了许多功能,包括文件操作、文本处理、网络通信、数学计算、日期和时间处理、多线程编程等。下面会介绍一些主要的模块。

    一、 文件和目录处理模块

    Python标准库中与文件和目录处理相关的一些模块如下:

    模块名称功能描述
    os提供了与操作系统交互的功能,包括文件和目录操作、环境变量等。
    os.path提供了处理文件路径的功能,包括路径拼接、分割、检查文件是否存在等。
    shutil用于高级文件操作,包括复制、移动、删除文件和目录,以及文件权限设置。
    glob用于查找符合特定模式的文件路径,支持通配符匹配。
    stat提供了获取文件和目录属性的功能,如文件大小、修改时间等。

    1.1 os模块

      os 模块是 Python 的标准库之一,提供了与操作系统交互的功能。它允许您执行与文件系统、目录、文件路径等相关的操作,相关教程详见另一篇帖子《Python3.11教程3:模块和包(pip/conda)、文件系统(os/ shutil/json/pickle/openpyxl/xlrd)》8.4章节。

    1.2 shutil 模块

    shutil 模块是Python标准库中的一个强大工具,用于文件和目录操作。它提供了许多函数,可用于复制、移动、删除文件和目录,以及执行各种文件操作任务,相关教程详见另一篇帖子《Python3.11教程3:模块和包(pip/conda)、文件系统(os/ shutil/json/pickle/openpyxl/xlrd)》8.5章节。

    1.3 文件通配符glob

      glob 模块用于查找文件和目录的路径,特别是在指定目录下查找符合特定模式的文件。其主要查找函数为glob.glob(),语法为:

    glob.glob(pathname, *, root_dir=None, dir_fd=None, recursive=False, include_hidden=False)
    
    • 1
    • pathname:搜索模式,可以是一个字符串(包含通配符 *?),表示要匹配的文件名或路径。例如,*.txt 可以匹配所有以 .txt 结尾的文件。

    • root_dir(可选参数):指定搜素的根目录,默认在当前目录进行搜索。

    • dir_fd(可选参数):表示在指定的文件描述符(File Descriptor)所代表的目录中进行搜索。

    • recursive(可选参数):默认 False,只在指定目录中搜索匹配项。若设置为 True,则会递归搜索子目录中的文件和目录。

    • include_hidden(可选参数):默认 False,如果设置为 True,则会搜索以点开头的隐藏文件和目录。

    *匹配任意字符序列,?匹配单个字符,

    import glob
    
    txt_files = glob.glob("*.txt")					# 查找所有以 .txt 结尾的文件
    ata_files = glob.glob("data*")					# 查找所有以 data 开头的文件
    numbered_files = glob.glob("*[0-9]*")			# 文件名中含有数字的文件
    
    # 匹配以 file 开头,后跟一个数字和一个字符,最后以 .txt 结尾的文件,如 file1.txt、fileA.txt,但不匹配 file10.txt。
    file[0-9]?.txt									
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    你也可以使用os模块和正则表达式来匹配文件:

    import os
    import re
    
    # 要匹配的目录和正则表达式模式
    directory = '/path/to/your/directory'
    pattern = r'my_pattern_\d+\.txt'  # 例如,匹配 "my_pattern_123.txt"
    
    # 使用正则表达式编译模式
    regex = re.compile(pattern)
    
    # 遍历目录中的文件和子目录
    for filename in os.listdir(directory):
        # 使用正则表达式匹配文件名
        if regex.match(filename):
            # 匹配成功,输出文件名或执行其他操作
            print(filename)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    1.4 stat

      在Python中,stat 模块( os.stat 模块)是一个用于获取文件和目录属性的模块。它允许您检索文件的元数据,如文件大小、修改时间、权限等,这些元数据信息对于文件和目录的管理和操作非常重要。

      stat 模块常用的函数为os.stat(path),用于指定路径的文件或目录的属性信息,最后返回一个包含各种元数据的命名元组,其主要属性有:

    属性描述
    st_mode文件的模式(权限),包括文件类型和权限标志位。
    st_size文件的大小(以字节为单位)。
    st_atime文件的最后访问时间(时间戳)。
    st_mtime文件的最后修改时间(时间戳)。
    st_ctime文件的创建时间(时间戳)。
    st_blocks文件占用的块数(Unix/Linux 文件系统中的块大小)。
    st_uid文件的用户标识符(用户所有者)。
    st_gid文件的组标识符(组所有者)。

    下面是一个简单的示例:

    import os
    import stat
    import time
    
    file_path = '/path/to/your/file.txt'
    file_stat = os.stat(file_path)					# 获取文件属性信息
    
    file_size = file_stat[stat.ST_SIZE]				# 获取文件大小(以字节为单位)
    print(f"File size: {file_size} bytes")
    
    # 获取文件最后修改时间并格式化为可读日期时间
    file_mtime = file_stat[stat.ST_MTIME]
    formatted_mtime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(file_mtime))
    print(f"Last modified time: {formatted_mtime}")
    
    file_stat 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    File size: 103368 bytes
    Last modified time: 2023-09-08 22:19:49
    os.stat_result(st_mode=33206, st_ino=1125899907060471, st_dev=4277431046, st_nlink=1, 
    st_uid=0, st_gid=0, st_size=103368, st_atime=1694182789, st_mtime=1694182789, st_ctime=1694045176)
    
    • 1
    • 2
    • 3
    • 4

    二、 sys模块

      sys模块是Python标准库的一部分,它允许您与Python解释器进行交互并访问与系统相关的信息。这个模块对于处理命令行参数、操作系统特定的功能以及控制Python解释器的行为非常有用。下面介绍sys模块的主要函数。

    函数/命令描述
    sys.argv命令行参数的列表,包括脚本名称。
    sys.exit([arg])退出程序,可选参数arg用于指定退出时的返回值。
    sys.path包含模块搜索路径的列表。
    sys.modules包含已加载模块的字典,以模块名为键,模块对象为值。
    sys.platform返回当前操作系统平台的名称(如’win32’、'linux’等)。
    sys.version返回Python解释器的版本信息。

    以下是一些示例:

    import sys
    
    # 假设你运行脚本时输入了以下命令:python myscript.py arg1 arg2
    print("命令行参数:", sys.argv)  		# 输出:['myscript.py', 'arg1', 'arg2']
    
    • 1
    • 2
    • 3
    • 4
    import sys
    
    def main():
        # 一些程序逻辑...
        if something_wrong:
            print("发生错误")
            sys.exit(1)  				# 退出程序,并返回退出状态码1
    
    if __name__ == "__main__":
        main()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2.1 命令行参数列表

      当你在命令行中运行一个 Python 脚本时,Python 解释器会把你输入的命令行信息转换成一个列表,这个列表被称为“命令行参数列表”。这个列表中包含了一些有用的信息,比如脚本的名字和其他参数。

      假设你有一个名为 script.py 的 Python 脚本,当你在命令行中输入python script.py arg1 arg2时,Python 解释器会将这些内容转换成一个列表,并存到 sys 模块的 argv 变量里,你可以使用 sys.argv 来进行访问:

    import sys
    
    # 获取命令行参数列表
    sys.argv
    
    • 1
    • 2
    • 3
    • 4
    ['script.py', 'arg1', 'arg2']    # 脚本名、多个参数名
    
    • 1

      如果你使用特殊的选项,例如 -c-m,Python 会在列表中提供额外的信息。例如,当你运行以下命令时:

    python -c "print('Hello, world!')"
    
    • 1

    列表会变成:

    ['-c', "print('Hello, world!')"]
    
    • 1

      这告诉你使用了 -c 选项,并且要执行的代码是 "print('Hello, world!')"。如果使用选项 -m modulesys.argv[0] 就是包含路径的模块的完整名称。

    2.2 -c和-m选项

      -c-m 是 Python 解释器的命令行选项,前者用于执行一行代码,后者用于运行指定模块。

    • -c 选项:

      -c commend 选项允许你在命令行中执行一行 Python 代码,这在需要快速执行一些简单的操作时很有用,而不需要创建一个完整的脚本文件。你可以将要执行的代码放在引号中(Python 语句经常包含空格或其他会被 shell 特殊对待的字符,通常建议用引号将整个 command 括起来)。下面是几个简单示例:

    1. 简单计算
    python -c "print(10 + 20)"
    
    • 1
    1. 多行代码块:你也可以在一行中编写多行代码,只需要使用 ; 分隔:
    python -c "x = 5; y = 10; print(x + y)"
    
    • 1
    1. 使用模块:你可以导入并使用 Python 的内置模块,例如时间模块。
    python -c "import time; print(time.strftime('%Y-%m-%d'))"
    
    • 1
    1. 创建列表:
    python -c "my_list = [1, 2, 3]; doubled = [x * 2 for x in my_list]; print(doubled)"
    
    • 1
    1. 条件语句
    python -c "x = 15; y = 10; print('x is greater' if x > y else 'y is greater')"
    
    • 1
    • -m选项

      -m module表示在 sys.path 中搜索指定模块,并以 __main__ 模块执行其内容。module是模块名,不包括文件扩展名(.py)。许多标准库模块都包含在执行时,都可以以脚本方式调用的代码,例如 timeit 模块:

    python -m timeit -s 'setup here' 'benchmarked code here'
    python -m timeit -h # for details
    
    • 1
    • 2

    你也可以额外指定模块的路径:

    # 运行my_package 包中的模块my_module
    python -m my_package.my_module
    
    • 1
    • 2

    有关此部分更多内容,请参考《命令行与环境》

    2.3 argparse

      argparse 模块提供了一种更复杂的机制来处理命令行参数,它可以帮助你创建命令行工具和脚本,使用户能够更方便地配置和运行你的程序。

    2.3.1 argparse使用逻辑

    一般来说,使用 argparse 的几个步骤如下:

    1. 导入 argparse 模块

    2. 使用 argparse.ArgumentParser 类创建命令行解析器对象。这个对象将用于定义和解析命令行参数。 在 description 参数中,你可以提供解析器的简短描述,以帮助用户理解如何使用你的命令行工具。

      parser = argparse.ArgumentParser(description='描述解析器的用途')
      
      • 1
    3. 添加命令行参数的定义:使用 parser.add_argument 方法来添加需要解析的命令行参数。这包括位置参数、可选参数和标志。你需要指定参数的名称、数据类型、默认值等信息。

      # 添加了一个名为 `--option` 的可选参数,它是整数类型,有默认为0,并提供了帮助信息。
      parser.add_argument('--option', type=int, default=0, help='可选参数的描述')
      
      • 1
      • 2
    4. 解析命令行参数并存储

      # 使用parser.parse_args() 方法来解析从命令行传递的参数,并将结果存储在变量中。
      args = parser.parse_args()
      
      • 1
      • 2
    5. 使用参数值:可以从 args 对象中访问解析后的参数值,并在程序中使用它们。

      option_value = args.option
      
      • 1
    6. 完成程序逻辑:最后,根据解析后的参数值执行程序的逻辑。根据参数的不同,你可以采取不同的操作。

      Yolov5 是一个用于目标检测的深度学习模型,通常会有一个 train.pydetect.py 等主要脚本,该脚本使用 argparse 来配置参数。下面演示一下如何使用这些参数来启动检测。

    # detect.py
    import argparse
    
    def parse_args():
        parser = argparse.ArgumentParser(description="Yolov5 目标检测")
        
        # 模型参数
        parser.add_argument('--model', type=str, default='yolov5s', help='模型类型 (yolov5s, yolov5m, yolov5l, yolov5x)')
        
        # 输入图像参数
        parser.add_argument('--image', type=str, default='input.jpg', help='输入图像路径')
        
        # 输出参数
        parser.add_argument('--output', type=str, default='output.jpg', help='输出图像路径')
        
        # 其他参数
        parser.add_argument('--conf-thres', type=float, default=0.3, help='置信度阈值')
        parser.add_argument('--iou-thres', type=float, default=0.5, help='IoU 阈值')
        
        args = parser.parse_args()
        return args
    
    def main():
        args = parse_args()
        
        # 执行目标检测操作
        model_type = args.model
        input_image = args.image
        output_image = args.output
        confidence_threshold = args.conf_thres
        iou_threshold = args.iou_thres
        
        # 这里可以调用 Yolov5 的检测函数,并传递参数进行检测操作
        # 例如,使用 Yolov5 的函数检测输入图像并输出结果到指定路径
        
        print(f"使用 {model_type} 模型进行目标检测")
        print(f"输入图像路径: {input_image}")
        print(f"输出图像路径: {output_image}")
        print(f"置信度阈值: {confidence_threshold}")
        print(f"IoU 阈值: {iou_threshold}")
        
    if __name__ == "__main__":
        main()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

      在上面的示例中,我们定义了一个 parse_args 函数解析命令行参数,并在其中定义了一些常见的 Yolov5 参数。接着,我们使用 parser.parse_args() 解析命令行参数,并将结果存储在 args 变量中。

      最后,在 main 函数中,我们使用解析后的参数来执行 Yolov5 的目标检测操作,这样,用户可以通过命令行指定不同的参数值来自定义检测的行为:

    python detect.py --model yolov5s --image input.jpg --output output.jpg --conf-thres 0.3 --iou-thres 0.5
    
    • 1
    2.3.2 add_argument()语法

      parser.add_argument 方法用于向命令行解析器中加命令行参数,当调用调用 parse_args() 方法时进行解析时,会按照以下规则将其解析为位置参数和可选参数(选项)。

    1. 位置参数(Positional Arguments):不带 --- 前缀的参数为位置参数,位置参数通常是必须提供的,并根据它们在命令行中的位置和顺序来解析。因此用户在使用命令行工具时必须按照预定的顺序提供这些参数,否则会解析出错。

      例如python script.py input.txt output.txt这行命令,input.txtoutput.txt 都是位置参数,用户必须按照正确的顺序提供它们,首先是输入文件,然后是输出文件。如果用户不提供这些位置参数,或者提供的参数数量不正确,命令行解析将会失败,并显示相应的错误消息。

    1. 可选参数(Optional Arguments):通常以前缀 ---引导的参数为可选参数,可选参数可以设置其默认值。

      还有一类特殊的可选参数称之为标志(Flags) ,它是布尔类型,用于表示一个状态或开关的存在。如果在命令行中提供了这个参数,那么它的值被设置为 True,否则默认为 False。你可以使用 action='store_true' 来定义标志参数。例如下面这行代码:

    parser.add_argument('--debug', action='store_true', help='启用调试模式')
    
    • 1

      代码中,--debug 参数被定义为一个标志参数,action='store_true'表示如果用户在命令行中输入了--debug参数,那么这个参数将被设置为 True(状态值),否则为False(默认值)。随后,这个参数的值将会传递给程序的其他部分,以决定是否启动调试功能。

    add_argument()方法的完整语法为:

    parser.add_argument(name or flags, action, nargs, const, default, type, choices, required, help, metavar)
    
    • 1

    参数详解:

    1. name or flags

      • name :字符串,通常表示位置参数的名称
      • flags :参数的标志,通常用于指定可选参数和标志的名称。可以是单个字符串(例如 '-input')或列表(例如 ['-i', '--input'])。

      parser.add_argument('-i', '--input', type=str, help='输入文件路径') 这种使用列表的写法是为了同时定义两个标志参数,一个是短标志 -i(简洁),另一个是长标志 --input(可读性好),它们都指向同一个参数——输入文件路径,用户可以自由选择。

    1. action:定义参数的动作,即在解析命令行参数时应执行的操作。常用的动作包括:
      • 'store':将命令行参数的值存储到一个变量中(默认动作)。
      • 'store_const':将一个常量值存储到一个变量中。
      • 'store_true''store_false':用于标志参数,分别表示存储 TrueFalse
      • 'append':将参数值追加到一个列表中,可用于多次指定相同参数。
      • 'count':计数参数的出现次数。
    2. nargs:指定此参数应该获取多少个命令行参数值。常见值为:
      1. None:默认值,表示参数只接受一个值。
      2. 整数:表示接受指定数量的参数值。例如 nargs=2,表示接受两个命令行参数
      3. '?':表示参数可以接受零个或一个值。不提供将取默认值。
      4. '*':表示参数可以接受零个或多个值,若有多个参数值,将被收集到一个列表中。
      5. '+':表示参数至少需要一个值,但也可以接受多个值。
    3. const:与 action='store_const' 结合使用,表示要存储的常量值。
    4. default:定义参数的默认值
    5. type:定义参数的数据类型(例如 intfloatstr 等)
    6. choices:定义参数的有效值范围
    7. required:布尔值,如果设置为 True,则用户必须在命令行中指定该参数;否则参数是可选的。
    8. help:提供参数的帮助文本,通常包括参数的描述和用法说明。
      10.metavar:自定义参数的显示名称,通常用于在帮助文本中代替参数的名称。

    下面我们创建一个script.py脚本,输入一下代码进行演示:

    # script.py
    import argparse
    
    # 创建 ArgumentParser 对象
    parser = argparse.ArgumentParser(description='演示 argparse 参数的用法')
    
    # 添加位置参数
    parser.add_argument('position_arg', type=int, help='一个位置参数')
    
    # 添加可选参数和标志参数
    parser.add_argument('--optional_arg', type=str, help='一个可选参数')
    parser.add_argument('--flag_arg', action='store_true', help='一个标志参数')
    
    # 添加具有可选值的参数,如果未提供,将使用默认值 const(这里是 42)。
    parser.add_argument('--value_arg', type=int, nargs='?', const=42, default=0, help='一个具有可选值的参数')
    
    # 添加参数的选择范围
    parser.add_argument('--choice_arg', choices=['apple', 'banana', 'cherry'], help='一个参数的选择范围')
    
    # 添加必需参数
    parser.add_argument('--required_arg', required=True, help='一个必需参数')
    
    # 添加参数的显示名称
    parser.add_argument('--display_arg', help='一个参数的显示名称', metavar='DISPLAY_NAME')
    
    # 解析命令行参数
    args = parser.parse_args()
    
    # 输出参数的值
    print('位置参数值:', args.position_arg)
    print('可选参数值:', args.optional_arg)
    print('标志参数值:', args.flag_arg)
    print('具有可选值的参数值:', args.value_arg)
    print('选择范围参数值:', args.choice_arg)
    print('必需参数值:', args.required_arg)
    print('显示名称参数值:', args.display_arg)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    你可以在命令行中使用不同的参数组合来测试这个示例,以了解各种参数的用法。例如:

    python script.py 10 --optional_arg optional_value --flag_arg --value_arg 5 --choice_arg apple --required_arg required_value --display_arg display_value
    
    • 1
    位置参数值: 10
    可选参数值: optional_value
    标志参数值: True
    具有可选值的参数值: 5
    选择范围参数值: apple
    必需参数值: required_value
    显示名称参数值: display_value
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    三、 数学

    3.1 math

      math 模块提供了各种数学函数和常数,用于执行数学运算。这些函数包括基本的数学运算、三角函数、指数和对数运算、取整函数等。以下是一些常见的 math 模块函数和常数:

    • 基本数学运算:math.sqrt()(平方根)、math.pow()(幂运算)、math.abs()(绝对值)等。
    • 三角函数:math.sin()(正弦)、math.cos()(余弦)、math.tan()(正切)等。
    • 对数和指数运算:math.log()(自然对数)、math.exp()(指数)、math.log10()(以 10 为底的对数)等。
    函数名描述
    math.ceil(x)向上取整:返回大于或等于 x 的最小整数
    math.floor(x)向下取整:返回小于或等于 x 的最大整数
    math.abs(x)返回x的绝对值
    math.sqrt(x)返回 x 的平方根。
    math.pow(x, y)返回 xy 次幂。
    math.exp(x)返回自然对数的底数 ex 次幂。
    math.log(x)返回 x 的自然对数。
    math.log10(x)返回 x 的以 10 为底的对数。
    math.sin(x)返回 x 的正弦值(弧度)。
    math.cos(x)返回 x 的余弦值(弧度)。
    math.tan(x)返回 x 的正切值(弧度)。
    math.pi数学常数 π(圆周率)。
    math.e自然对数的底数 e
    math.inf正无穷大。
    math.nan非数值(Not-a-Number)。

      NumPy是一个常用的第三方库,也包含了许多数学函数和常数,它提供了丰富的数值运算功能。以下是常见的处理函数:

    函数名描述
    numpy.array(iterable)从可迭代对象创建一个 NumPy 数组。
    numpy.arange(start, stop, step)创建一个范围内的值的数组。
    numpy.linspace(start, stop, num)在指定范围内生成指定数量的均匀间隔的值。
    numpy.zeros(shape)创建一个全零数组。
    numpy.ones(shape)创建一个全一数组。
    numpy.eye(N)创建一个单位矩阵(对角线上元素为 1,其它为 0)。
    numpy.random.rand(shape)生成指定形状的随机数数组(0 到 1 之间)。
    numpy.sum(array)计算数组中元素的和。
    numpy.mean(array)计算数组中元素的平均值。
    numpy.median(array)计算数组中元素的中位数。
    numpy.min(array)找到数组中的最小值。
    numpy.max(array)找到数组中的最大值。
    numpy.std(array)计算数组中元素的标准差。
    numpy.var(array)计算数组中元素的方差。
    numpy.dot(a, b)计算两个数组的点积(内积)。
    numpy.cross(a, b)计算两个数组的叉积。
    numpy.sin(array)计算数组中元素的正弦值。
    numpy.cos(array)计算数组中元素的余弦值。
    numpy.tan(array)计算数组中元素的正切值。
    numpy.exp(array)计算数组中元素的指数值。
    numpy.log(array)计算数组中元素的自然对数。
    numpy.sqrt(array)计算数组中元素的平方根。
    numpy.pi数学常数 π(圆周率)。
    numpy.e自然对数的底数 e

    3.2 random

    random 模块用于生成随机数和进行随机数操作,以下是一些 random 模块的常用功能:

    random函数名描述
    random.random()生成0到1之间的随机浮点数。
    random.randint(a, b)生成指定范围内的随机整数。
    random.uniform(a, b)生成指定范围内的随机浮点数。
    random.seed(a=None, version=2)设置随机数生成的种子值,以确保可重复的随机数序列。
    random.randrange(start, stop, step)生成指定范围内的随机整数,可以指定步长。
    random.choices(population, weights=None, k=1)根据权重从序列中随机选择多个元素。

    下面是示例代码:

    import random
    
    # 生成指定范围内的随机整数
    random_integer = random.randint(1, 10)
    print("随机整数:", random_integer)
    
    # 生成指定范围内的随机浮点数
    random_uniform = random.uniform(0, 1)
    print("随机浮点数:", random_uniform)
    
    # 设置随机种子以确保可重复的随机数序列
    random.seed(42)
    random_integer = random.randint(1, 10)
    print("设置随机种子后的随机整数:", random_integer)
    
    # 生成指定范围内的随机整数,可以指定步长
    random_range = random.randrange(1, 20, 2)  # 生成1到19之间的奇数
    print("随机范围内的随机整数:", random_range)
    
    # 根据权重从序列中随机选择多个元素
    options = ["apple", "banana", "cherry", "date"]
    weights = [2, 1, 1, 2]  # 对应每个选项的权重
    random_choices = random.choices(options, weights=weights, k=3)
    print("根据权重随机选择的元素:", random_choices)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    3.3 numpy生成随机数

    以下是 NumPy 中与随机数相关的一些常用函数

    函数名描述
    numpy.random.rand(d0, d1, ..., dn)生成指定维度的均匀分布的随机浮点数。
    numpy.random.randn(d0, d1, ..., dn)生成指定维度的标准正态分布的随机浮点数。
    numpy.random.randint(low, high=None, size=None, dtype=int)生成指定范围内的随机整数。
    numpy.random.uniform(low=0.0, high=1.0, size=None)生成指定范围内的均匀分布的随机浮点数。
    numpy.random.normal(loc=0.0, scale=1.0, size=None)生成指定均值和标准差的正态分布的随机浮点数。
    numpy.random.seed(seed=None)设置随机数生成的种子值,以确保可重复的随机数序列。
    numpy.random.choice(a, size=None, replace=True, p=None)从数组中随机选择元素。
    numpy.random.shuffle(x)随机打乱数组的顺序。
    numpy.random.permutation(x)返回一个随机排列的数组副本。

    示例代码:

    import numpy as np
    
    # 生成指定维度的均匀分布的随机浮点数
    rand_array = np.random.rand(2, 3)  # 2行3列的随机浮点数数组
    print("随机浮点数数组:")
    print(rand_array)
    
    # 生成指定维度的标准正态分布的随机浮点数
    randn_array = np.random.randn(2, 3)  # 2行3列的标准正态分布的随机浮点数数组
    print("\n标准正态分布的随机浮点数数组:")
    print(randn_array)
    
    # 生成指定范围内的随机整数
    randint_value = np.random.randint(1, 10, size=(2, 3))  # 2行3列的随机整数数组
    print("\n随机整数数组:")
    print(randint_value)
    
    # 生成指定范围内的均匀分布的随机浮点数
    uniform_value = np.random.uniform(0, 1, size=(2, 3))  # 2行3列的均匀分布的随机浮点数数组
    print("\n均匀分布的随机浮点数数组:")
    print(uniform_value)
    
    # 生成指定均值和标准差的正态分布的随机浮点数
    normal_value = np.random.normal(0, 1, size=(2, 3))  # 2行3列的正态分布的随机浮点数数组
    print("\n正态分布的随机浮点数数组:")
    print(normal_value)
    
    # 设置随机种子以确保可重复的随机数序列
    np.random.seed(42)
    rand_seed = np.random.rand(2, 3)
    print("\n设置随机种子后的随机浮点数数组:")
    print(rand_seed)
    
    # 从数组中随机选择元素
    array_to_choose = np.array([1, 2, 3, 4, 5])
    choices = np.random.choice(array_to_choose, size=3, replace=False)
    print("\n从数组中随机选择的元素:")
    print(choices)
    
    # 随机打乱数组的顺序
    shuffled_array = np.arange(10)
    np.random.shuffle(shuffled_array)
    print("\n随机打乱顺序后的数组:")
    print(shuffled_array)
    
    # 返回一个随机排列的数组副本
    permutation_array = np.random.permutation(10)
    print("\n随机排列的数组副本:")
    print(permutation_array)
    
    # 生成伽玛分布的随机浮点数
    gamma_values = np.random.gamma(2, 2, size=(2, 3))  # 2行3列的伽玛分布的随机浮点数数组
    print("\n伽玛分布的随机浮点数数组:")
    print(gamma_values)
    
    # 生成指数分布的随机浮点数
    exponential_values = np.random.exponential(2, size=(2, 3))  # 2行3列的指数分布的随机浮点数数组
    print("\n指数分布的随机浮点数数组:")
    print(exponential_values)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59

    四、 日期和时间

    4.1 time

      Python 标准库中的 time 模块提供了与时间相关的功能和函数,用于处理时间、日期和与系统时间有关的操作。在此之前,先介绍两个基本概念:

    1. 时间戳(Timestamp):一种在计算机系统中广泛使用的时间表示方式,特别是用于时间的比较和计算。

      • 时间戳是一种表示时间的方式,通常是指从1970年1月1日午夜(UTC,协调世界时)以来的秒数,这被称为“UNIX时间戳”或“Epoch时间戳”。
      • 时间戳通常用于计算和比较时间,特别是在进行时间差计算、时间间隔计算以及执行时间戳的加减运算时非常有用。

      时间戳通常还可以包含小数部分。例如,Unix时间戳中的时间 “2023-09-12 15:30:00” 可以表示为类似于 1689330600(秒数)或 1689330600000(毫秒数)的数字;“secs” 表示其中的秒数部分(不包括毫秒)

    1. 时间元组(Time Tuple):一种人类友好的日期时间表示方法,可以轻松地访问和操作各个部分。

      • 时间元组是一个包含多个时间相关字段的数据结构,通常包括年、月、日、时、分、秒等,在time模块中用time.struct_time 类型表示。
      • 时间元组在处理日期时间的高级操作时非常有用,例如格式化和解析日期时间、进行时区转换等。

      在Python中,你可以使用 time.time() 获取当前时间的时间戳,以及使用 time.gmtime()time.localtime() 获取当前时间的时间元组。

    以下是一些 time 模块的主要功能和函数:

    1. 时间戳操作

      • time.time(): 返回当前时间的时间戳,通常是自 1970 年 1 月 1 日午夜(协调世界时)以来的秒数。
      • time.mktime(t):将本地时间元组 t 转换为时间戳。其中,t 是一个包含以下九个字段的本地时间元组:
      字段名称含义字段名称含义
      tm_year年份,4 位数(例如,2023)。tm_sec秒,取值范围为 0 到 61(60 和 61 用于闰秒)。
      tm_mon月份,取值范围为 1 到 12。tm_wday星期中的第几天,取值范围为 0(星期一)到 6(星期日)。
      tm_mday月中的日,取值范围为 1 到 31。tm_yday年份中的第几天,取值范围为 1 到 366(考虑闰年)。
      tm_hour小时,取值范围为 0 到 23。tm_isdst是否为夏令时(Daylight Saving Time,DST),取值为 -1(无关)、0(不是夏令时)或 1(是夏令时)。
      tm_min分钟,取值范围为 0 到 59。
      • time.gmtime([secs]):将时间戳 secs 转换为 UTC 时间元组。
      • time.localtime([secs]):将时间戳 secs 转换为本地时间元组。
    import time
    
    # 获取当前时间的时间戳
    current_timestamp = time.time()					
    
    # 创建一个本地时间元组
    local_time_tuple = (2023, 9, 12, 15, 30, 0, 1, 255, -1)
    
    # 使用mktime将本地时间元组转换为时间戳
    local_timestamp = time.mktime(local_time_tuple)
    print("本地时间元组转换的时间戳:", local_timestamp)
    
    # 使用gmtime将时间戳转换为UTC时间元组
    utc_time_tuple = time.gmtime(current_timestamp)
    print("UTC时间元组:", utc_time_tuple)
    
    # 使用localtime将时间戳转换为本地时间元组
    local_time_tuple2 = time.localtime(current_timestamp)
    print("本地时间元组:", local_time_tuple2)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    本地时间元组转换的时间戳: 1694503800.0
    UTC时间元组: time.struct_time(tm_year=2023, tm_mon=9, tm_mday=12, tm_hour=8, tm_min=6, tm_sec=13, tm_wday=1, tm_yday=255, tm_isdst=0)
    本地时间元组: time.struct_time(tm_year=2023, tm_mon=9, tm_mday=12, tm_hour=16, tm_min=6, tm_sec=13, tm_wday=1, tm_yday=255, tm_isdst=0)
    
    • 1
    • 2
    • 3
    1. 时间元组操作

      • time.struct_time:用于表示时间的元组,包括年、月、日、时、分、秒等各个部分。时间元组的各个字段(如年、月、日等)可以通过索引或命名属性访问,以下是详细信息:
      字段名称含义字段名称含义
      tm_year年份,4 位数(例如,2023)。tm_sec秒,取值范围为 0 到 61(60 和 61 用于闰秒)。
      tm_mon月份,取值范围为 1 到 12。tm_wday星期中的第几天,取值范围为 0(星期一)到 6(星期日)。
      tm_mday月中的日,取值范围为 1 到 31。tm_yday年份中的第几天,取值范围为 1 到 366(考虑闰年)。
      tm_hour小时,取值范围为 0 到 23。tm_zone时区名称(仅在某些系统中支持,通常为 None)。
      tm_min分钟,取值范围为 0 到 59。tm_gmtoffUTC 偏移量(仅在某些系统中支持,通常为 None)。
      • time.strftime(format[, t]):将时间元组 t(默认为当前时间)根据指定的格式字符串 format 格式化为字符串。
      • time.strptime(string[, format]):将时间字符串 string 解析为时间元组,根据指定的格式字符串 format

    format表示的日期时间格式化代码含义如下:

    格式化代码含义格式化代码含义
    %Y年份,4 位数(例如,2023)%S秒数,00-59
    %y年份,2 位数(00-99)%A星期的全名(例如,Monday)
    %m月份,01-12%a星期的缩写(例如,Mon)
    %d月中的日,01-31%B月份的全名(例如,January)
    %H小时(24 小时制),00-23%b月份的缩写(例如,Jan)
    %I小时(12 小时制),01-12%Z时区的名称
    %M分钟,00-59
    import time
    
    # 创建一个自定义的时间元组
    now_tuple = (2023, 9, 12, 15, 30, 0, 1, 255, -1)
    
    # 使用time.struct_time()创建时间元组对象
    now = time.struct_time(now_tuple)
    
    # 访问时间元组的字段
    year = now.tm_year
    
    print("年份:", year)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    年份: 2023
    
    • 1
    # 格式化时间
    import time
    
    # 1. 使用 time.strftime() 将时间元组格式化为字符串
    current_time = time.localtime()
    formatted_time = time.strftime("%Y-%m-%d %H:%M:%S", current_time)
    print("当前时间的格式化字符串:", formatted_time)
    
    # 2. 使用 time.strptime() 将时间字符串解析为时间元组
    date_string = "2023-09-12 15:30:00"
    format = "%Y-%m-%d %H:%M:%S"
    parsed_time = time.strptime(date_string, format)
    print("解析的时间元组:", parsed_time)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    1. 睡眠和定时

      • time.sleep(secs):使程序休眠 secs 秒,用于定时操作。
      • time.perf_counter():返回高精度的性能计数器值,通常用于性能测量。
    2. 其他功能

      • time.clock():返回 CPU 时间或系统时间(取决于平台)的秒数。
      • time.process_time():返回当前进程的 CPU 时间。
    3. 时区信息

      • time.timezone:本地时区与协调世界时(UTC)的秒差。通常为负数,表示东半球时区。
      • time.tzname:本地时区的名称。

    4.2 datetime

    参考:datetime — 基本日期和时间类型
      Python 中处理时间的标准库是 datetimedatetime 模块提供了处理日期和时间的功能,包括日期算术、日期格式化、日期解析等操作。以下是一些常用的 datetime 模块中的类和函数:

    datetime常用类描述
    datetime.datetime日期和时间的组合类,用于表示具体的日期和时间。可以创建日期时间对象、执行日期时间的算术运算、获取日期时间的各个部分(年、月、日、时、分、秒等)等。
    datetime.datedatetime.datetime的子类,用于表示日期的类,包括年、月、日(不包括时间)。
    datetime.timedatetime.datetime的子类,用于表示日期的类,包括时、分、秒、微秒(不包含日期)。
    datetime.timedelta用于表示时间间隔或持续时间的类,用于进行日期时间的加减法运算。
    datetime.tzinfo抽象基类,用于表示时区信息。
    datetime.timezone时区信息的具体实现类,Python 3.2+ 新增。
    4.2.1 datetime.datetime类

    以下是 datetime.datetime 类中主要方法以及参数说明:

    1. datetime(year, month, day, hour=0, minute=0, second=0, microsecond=0): 用于创建一个新的 datetime 对象。

      • year, month, day:表示年月日,必须。
      • hour, minute, second, microsecond:时分秒毫秒,可选,默认为0
      import datetime
      
      dt = datetime.datetime(2023, 9, 12, 15, 30, 0)
      
      • 1
      • 2
      • 3
    2. replace(year=None, month=None, day=None, hour=None, minute=None, second=None, microsecond=None)

      • 创建一个新的 datetime 对象,用指定的参数替换原对象的对应部分。
      • 每个参数都是可选的,未指定的部分将保持不变。
      import datetime
      
      now = datetime.datetime.now()
      new_date = now.replace(year=2024, month=1)
      
      • 1
      • 2
      • 3
      • 4
    创建 datetime 对象的方法描述参数说明
    datetime.now(tz=None)获取当前日期和时间的 datetime 对象。tz:时区信息(可选,默认为 None,表示本地时区)。
    datetime.today()返回当前日期和时间的datetime对象,不带时区信息。
    datetime.utcfromtimestamp(timestamp)从UTC时间戳创建一个datetime对象。
    datetime.fromisoformat(date_string)从ISO格式的日期字符串创建一个datetime对象。
    datetime.strptime(date_string, format)从字符串解析日期时间,并返回一个 datetime 对象。date_string:待解析的日期时间字符串。
    format:格式化字符串,用于指导日期字符串的解析。
    date()返回一个新的 datetime.date 对象,表示日期部分。
    time()返回一个新的 datetime.time 对象,表示时间部分。
    datetime.combine(date, time)将一个日期对象和一个时间对象合并为一个datetime对象。
    方法描述
    strftime(format)datetime 对象格式化为指定格式的字符串。
    datetime.weekday()返回日期的星期几,星期一为0,星期日为6。
    datetime.isoweekday()返回日期的星期几,星期一为1,星期日为7。
    from datetime import datetime
    datetime.fromisoformat('2011-11-04')
    datetime.datetime(2011, 11, 4, 0, 0)
    datetime.fromisoformat('20111104')
    datetime.datetime(2011, 11, 4, 0, 0)
    datetime.fromisoformat('2011-11-04T00:05:23')
    datetime.datetime(2011, 11, 4, 0, 5, 23)
    datetime.fromisoformat('2011-11-04T00:05:23Z')
    datetime.datetime(2011, 11, 4, 0, 5, 23, tzinfo=datetime.timezone.utc)
    datetime.fromisoformat('20111104T000523')
    datetime.datetime(2011, 11, 4, 0, 5, 23)
    datetime.fromisoformat('2011-W01-2T00:05:23.283')
    datetime.datetime(2011, 1, 4, 0, 5, 23, 283000)
    datetime.fromisoformat('2011-11-04 00:05:23.283')
    datetime.datetime(2011, 11, 4, 0, 5, 23, 283000)
    datetime.fromisoformat('2011-11-04 00:05:23.283+00:00')
    datetime.datetime(2011, 11, 4, 0, 5, 23, 283000, tzinfo=datetime.timezone.utc)
    datetime.fromisoformat('2011-11-04T00:05:23+04:00')   
    datetime.datetime(2011, 11, 4, 0, 5, 23,
        tzinfo=datetime.timezone(datetime.timedelta(seconds=14400)))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    import datetime
    
    # 获取当前日期和时间
    now = datetime.datetime.now()
    print("当前日期和时间:", now)
    
    # 格式化日期时间对象为字符串
    formatted_date = now.strftime("%Y-%m-%d %H:%M:%S")
    print("格式化后的日期时间:", formatted_date)
    
    # 解析字符串为日期时间对象
    date_string = "2023-09-12 15:30:00"
    format = "%Y-%m-%d %H:%M:%S"
    parsed_date = datetime.datetime.strptime(date_string, format)
    print("解析后的日期时间对象:", parsed_date)
    
    # 获取日期部分和时间部分
    date_part = now.date()
    time_part = now.time()
    print("日期部分:", date_part)
    print("时间部分:", time_part)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

      在上述代码中,format = "%Y-%m-%d %H:%M:%S" 是用来指定 date_string 字符串的日期时间格式。下表列举了所有格式化代码以及它们的含义:

    格式化代码含义格式化代码含义
    %Y四位数的年份(例如:2023)%b%h月份的缩写名称(例如:Sep)
    %y年份,2 位数(00-99)%c日期时间的本地表示(例如:Tue Sep 12 15:30:00 2023)
    %m两位数的月份(01 到 12)%j年份中的第几天(001 到 366)
    %d两位数的日期(01 到 31)%U年份中的第几周,以星期日为一周的开始(00 到 53)
    %H2小时数(24小时制),00-23%W年份中的第几周,以星期一为一周的开始(00 到 53)
    %I小时数(12 小时制),01-12%p本地化的 AM 或 PM 。
    %M两位数的分钟(00 到 59)%w星期的数值表示(0 表示星期日,1 表示星期一,依此类推)
    %S两位数的秒数(00 到 59)%x日期的本地表示(例如:09/12/23)
    %A星期的完整名称(例如:Monday)%X时间的本地表示(例如:15:30:00)
    %a星期的缩写名称(例如:Mon)%Z时区的名称(例如:UTC)
    %B月份的完整名称(例如:September)%%百分号字符(%)
    import datetime
    
    now = datetime.datetime.now()
    # %c:日期时间的本地表示
    print("本地日期时间:", now.strftime("%c")) 	 # 本地日期时间: Mon Sep 12 15:30:00 2023
    # %x:日期的本地表示
    print("本地日期:", now.strftime("%x"))  		 # 本地日期: 09/12/23
    
    # %X:时间的本地表示
    print("本地时间:", now.strftime("%X")) 		 # 本地时间: 15:30:00
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    4.2.2 datetime.timedelta类

      datetime.timedelta 类是 Python 中用于表示时间间隔或时间差的类,主要用于进行日期时间的加减法运算。以下是 datetime.timedelta 类的主要方法以及它们的参数含义:

    datetime.timedelta类主要方法描述
    total_seconds()返回时间间隔的总秒数,包括天数、秒数和微秒数。
    days返回时间间隔的天数部分。
    seconds返回时间间隔的秒数部分,不包括天数部分。
    microseconds返回时间间隔的微秒数部分。

    两个不相等的 timedelta 类对象最小的间隔为 timedelta(microseconds=1)

      另外还有__add__(other)__sub__(other)魔法方法,用于时间间隔的加减法运算。这些方法的示例代码如下:
    import datetime

    # 创建两个时间间隔对象
    delta1 = datetime.timedelta(days=2, hours=3, minutes=30)
    delta2 = datetime.timedelta(days=1, seconds=7200)  				# 2小时
    
    # total_seconds() 方法:获取总秒数
    total_seconds1 = delta1.total_seconds()
    total_seconds2 = delta2.total_seconds()
    print("总秒数1:", total_seconds1)  								# 总秒数1: 187800.0
    print("总秒数2:", total_seconds2)  								# 总秒数2: 7200.0
    
    # days 属性:获取天数部分
    days1 = delta1.days
    days2 = delta2.days
    print("天数1:", days1) 											 # 天数1: 2
    print("天数2:", days2)  											 # 天数2: 1
    
    # seconds 属性:获取秒数部分
    seconds1 = delta1.seconds
    seconds2 = delta2.seconds
    print("秒数1:", seconds1)  										 # 秒数1: 12600
    print("秒数2:", seconds2)  										 # 秒数2: 7200
    
    # microseconds 属性:获取微秒数部分
    microseconds1 = delta1.microseconds
    microseconds2 = delta2.microseconds
    print("微秒数1:", microseconds1)  								 # 微秒数1: 0
    print("微秒数2:", microseconds2)  								 # 微秒数2: 0
    
    # __add__() 方法:加法运算
    result1 = delta1 + delta2
    print("加法运算结果:", result1)  									 # 加法运算结果: 3 days, 5:30:00
    
    # __sub__() 方法:减法运算
    result2 = delta1 - delta2
    print("减法运算结果:", result2) 									 # 减法运算结果: 0:30:00
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    4.2.3 datetime.timezone类

    datetime.timezone类主要是表示时区信息,以下是其基本方法:

    datetime.timezone类主要方法描述
    utcoffset(dt)返回给定日期时间对象 dt 在该时区下的 UTC 偏移量(时间差)。
    tzname(dt)返回给定日期时间对象 dt 在该时区下的名称。
    __eq__(other)__ne__(other)用于比较两个时区对象是否不相等。
    import datetime
    
    # 创建一个自定义时区对象(UTC+5)
    custom_timezone = datetime.timezone(datetime.timedelta(hours=5))
    
    # 获取当前日期时间
    now = datetime.datetime.now()
    
    # 获取UTC偏移量
    offset = custom_timezone.utcoffset(now)
    print("UTC偏移量:", offset)
    
    # 获取时区名称
    name = custom_timezone.tzname(now)
    print("时区名称:", name)
    
    custom_timezone ==now 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    UTC偏移量: 5:00:00
    时区名称: UTC+05:00
    False
    
    • 1
    • 2
    • 3

    五、 threading :多线程

      此部分内容详见《python网络爬虫指南二:多线程网络爬虫、动态内容爬取(待续)》第一章。

  • 相关阅读:
    Oracle Form Bulider 打开后提示 FRM-18018:Failed to load the following objects
    植物根系基因组与数据分析
    【电源专题】LDO如何防止出现反向电流
    【webrtc】 对视频质量的码率控制的测试与探索
    风靡全球25年的重磅IP,新作沦为脚本乐园
    详解4种类型的爬虫技术
    【Promise】黑马vue视频笔记(十一)
    1.(vue3.x+vite)创建工程
    Taurus.MVC WebMVC 入门开发教程7:部分视图和页面片段(结束篇)
    对C语言函数的再认识
  • 原文地址:https://blog.csdn.net/qq_56591814/article/details/132765438