Python基础入门(二)

发布于:2025-04-16 ⋅ 阅读:(31) ⋅ 点赞:(0)

Python基础入门

一、文件操作

1.1 文件的打开与关闭

open() 文件打开函数使用
file = open("test.txt", "r")
文件打开模式
  • r: 读取(默认模式,文件必须存在)
  • w: 写入(覆盖已有文件)
  • a: 追加(在文件末尾添加)
  • x: '创建新文件(文件已存在则失败)
  • b: 二进制模式(可与r/w/a/x组合)
  • t: 文本模式(默认,可与r/w/a/x组合)
  • +: 读写模式(可与r/w/a组合)

常用模式组合:

  • r 或 rt : 读取文本文件(默认)
  • w 或 wt : 写入文本文件(覆盖)
  • a 或 at : 追加文本内容
  • rb : 读取二进制文件
  • wb : 写入二进制文件
  • r+ : 读写文本文件(不截断)
  • w+ : 读写文本文件(截断)
  • a+ : 读写文本文件(追加)
with 语句管理文件资源
with open("test.txt", "r") as file:
    content = file.read()
close() 文件关闭函数使用
# 1. 使用with语句自动关闭(推荐)
with open('info.txt', 'r', encoding='utf-8') as f:
    content = f.read()
# 文件在这里自动关闭
print(f.closed)

# 2. 手动关闭文件
f = open('info.txt', 'r', encoding='utf-8')
try:
    content = f.read()
finally:
    f.close()  # 确保文件被关闭

# 3. 检查文件是否关闭
f = open('info.txt', 'r', encoding='utf-8')
print(f.closed)
f.close()
print(f.closed)
结果为:
True
False
True

说明:

  1. with 语句会在代码块执行完毕后自动关闭文件,即使发生异常也会关闭
  2. 手动打开文件时,必须显式调用 close() 方法
  3. 可以通过 文件对象.closed 属性检查文件是否已关闭
  4. 未关闭文件可能导致资源泄漏和数据丢失

最佳实践:始终使用 with 语句处理文件操作。

1.2 文件读写操作

读取文件内容
  • read() 读取整个文件,readline() 读取一行,readlines() 读取所有行。
  • 大文件推荐使用 readline() 或直接迭代文件对象
  • 小文件可以使用 read() 或 readlines()

提前准备好文件example.txt,并写入部分内容

# 1. read() - 读取整个文件内容
with open('example.txt', 'r', encoding='utf-8') as f:
    content = f.read()  # 返回整个文件内容的字符串
    print("read()结果:")
    print(content)

# 2. readline() - 每次读取一行
with open('example.txt', 'r', encoding='utf-8') as f:
    print("\nreadline()结果:")
    line = f.readline()  # 读取第一行
    while line:  # 当line不为空时继续读取
        print(line.strip())  # 去除行尾换行符
        line = f.readline()  # 读取下一行

# 3. readlines() - 读取所有行并返回列表
with open('example.txt', 'r', encoding='utf-8') as f:
    lines = f.readlines()  # 返回包含所有行的列表
    print("\nreadlines()结果:")
    for line in lines:
        print(line.strip())
结果为:
read()结果:
这是一些示例文本
第二行内容      
这是追加的内容  


readline()结果: 
这是一些示例文本
第二行内容      
这是追加的内容  

readlines()结果:
这是一些示例文本
第二行内容
这是追加的内容
写入文件内容
  • write() 写入字符串,writelines() 写入字符串列表。
# write() - 写入字符串
with open('output1.txt', 'w', encoding='utf-8') as f:
    f.write("这是第一行内容\n")  # 写入字符串
    f.write("这是第二行内容\n")  # 需要手动添加换行符

# writelines() - 写入字符串列表
lines = ["第一行\n", "第二行\n", "第三行\n"]
with open('output2.txt', 'w', encoding='utf-8') as f:
    f.writelines(lines)  # 写入字符串列表,不会自动添加换行符

# 结合使用示例
data = ["姓名: 张三\n", "年龄: 25\n", "职业: 工程师\n"]
with open('info.txt', 'w', encoding='utf-8') as f:
    f.write("=== 个人信息 ===\n")  # 使用write写入单行

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

1.3 文件和目录管理

  • 使用 os 模块进行文件和目录操作,如 os.listdir() 列出目录内容。
import os
# 1. 检查文件/目录是否存在
print(os.path.exists('example.txt'))  # 检查文件是否存在
print(os.path.exists('mydir'))        # 检查目录是否存在
# 2. 创建目录
os.makedirs('mydir/subdir', exist_ok=True)  # 创建多级目录
# 3. 列出目录内容
print(os.listdir('.'))  # 列出当前目录所有文件和子目录
# 4. 重命名文件/目录
os.rename('example.txt', 'new_example.txt')
# 5. 删除文件
os.remove('new_example.txt')
# 6. 删除空目录
os.rmdir('mydir/subdir')
# 7. 获取文件大小
print(os.path.getsize('data.csv'))
# 8. 获取文件绝对路径
print(os.path.abspath('data.csv'))
# 9. 路径拼接
new_path = os.path.join('mydir', 'subdir', 'file.txt')
print(new_path)  # 输出: mydir/subdir/file.txt
# 10. 判断是否是文件/目录
print(os.path.isfile('data.csv'))  # 是否是文件
print(os.path.isdir('mydir'))     # 是否是目录
结果为:
True
True
['data.csv', 'data.json', 'data.txt', 'demo1.py', 'demo2.py', 'example.txt', 'file1.py', 'file2.py', 
'func_demo.py', 'image.png', 'info.txt', 'mydir', 'oop2.py', 'oop_demo.py', 'output.txt', 'output1.txt', 'output2.txt', 'tuple_demo.py']
26
E:\space\python\base\data.csv
mydir\subdir\file.txt
True
True
  • shutil 模块用于高级文件操作,如复制文件等。
import shutil
# 11. 复制文件
shutil.copy('data.csv', 'data_copy.csv')
# 12. 递归复制目录
shutil.copytree('mydir', 'mydir_backup')
# 13. 移动/重命名文件
shutil.move('data_copy.csv', 'mydir/data.csv')
# 14. 递归删除目录
shutil.rmtree('mydir_backup')
# 15. 创建压缩包
shutil.make_archive('backup', 'zip', 'mydir')
# 16. 获取磁盘使用情况
usage = shutil.disk_usage('.')
print(f"总空间: {usage.total/1024/1024:.2f}MB")
print(f"已用空间: {usage.used/1024/1024:.2f}MB")
print(f"剩余空间: {usage.free/1024/1024:.2f}MB")

二、异常处理

2.1 异常的概念

异常是程序执行过程中出现的错误事件,它会中断程序的正常执行流程。 Python 脚本遇到无法处理的状况时,会抛出异常。

常见异常类型
  • SyntaxError 语法错误。解释器遇到不符合 Python 语法规则的代码时会抛出该异常。
# 错误示例:缺少冒号
if True
    print("Hello")
结果为:
 if True
           ^
SyntaxError: expected ':'
  • IndentationError 缩进错误。Python 使用缩进来表示代码块,当缩进不符合规则时会抛出该异常。
def func():
print("Hello")  # 缩进错误
结果为:
    print("Hello")  # 缩进错误
    ^
IndentationError: expected an indented block after function definition on line 1
  • TypeError 类型错误。当操作或函数应用于不适当类型的对象时会抛出该异常。
result = "5" + 3  # 不能将字符串和整数直接相加
结果为:
   result = "5" + 3  # 不能将字符串和整数直接相加
TypeError: can only concatenate str (not "int") to str
  • ZeroDivisionError 除零错误。当尝试用一个数除以零或对零取模时会抛出该异常。
result = 10 / 0  # 除数不能为零
结果为:
    result = 10 / 0  # 除数不能为零
ZeroDivisionError: division by zero
  • IndexError 索引错误。当尝试访问序列(如列表、元组、字符串)中不存在的索引时会抛出该异常。
my_list = [1, 2, 3]
print(my_list[3])  # 列表索引超出范围
结果为:
    print(my_list[3])  # 列表索引超出范围
IndexError: list index out of rang
  • KeyError 键错误。当尝试访问字典中不存在的键时会抛出该异常。
my_dict = {"name": "张三", "age": 25}
print(my_dict["address"])  # 字典中不存在 "address" 这个键
结果为:
    print(my_dict["address"])  # 字典中不存在 "address" 这个键
KeyError: 'address'
  • NameError 名称错误。当使用一个未定义的变量、函数或类名时会抛出该异常。
print(unknown_variable)  # unknown_variable 未定义
结果为:
    print(unknown_variable)  # unknown_variable 未定义
NameError: name 'unknown_variable' is not defined
  • ValueError 值错误。当函数接收到正确类型但无效值的参数时会抛出该异常。
num = int("abc")  # 不能将非数字字符串转换为整数
结果为:
    num = int("abc")  # 不能将非数字字符串转换为整数
ValueError: invalid literal for int() with base 10: 'abc'

2.2 异常处理机制

try 块用于包裹可能会抛出异常的代码。当 Python 执行到 try 块中的代码时,如果发生异常,程序会立即停止当前 try 块中的执行,转而跳转到对应的 except 块进行异常处理。
except 块用于捕获并处理 try 块中抛出的异常。可以有多个 except 块,分别处理不同类型的异常。如果没有指定异常类型, except 块会捕获所有异常。
finally 块是可选的,无论 try 块中是否发生异常,也无论 except 块是否执行, finally 块中的代码总会被执行。通常用于释放资源,比如关闭文件、数据库连接等。

try-except 语句
try:
    result = 10 / 0
except ZeroDivisionError:
    print("除数不能为零")
结果为:
除数不能为零
elsefinally 子句
  • elsetry 块无异常时执行,finally 无论是否有异常都会执行。
自定义异常
# 定义自定义异常类
class MyError(Exception):
    pass

# 定义一个更复杂的自定义异常类,继承Exception类,添加error_code 属性,并重写__str__方法,用于输出包含错误码的错误信息
class ComplexError(Exception):
    def __init__(self, message, error_code):
        super().__init__(message)
        self.error_code = error_code

    def __str__(self):
        return f"Error Code {self.error_code}: {super().__str__()}"

try:
    raise MyError("这个是自定义异常")
except MyError as e:
    print(e)

try:
    # 抛出携带错误码的自定义异常
    raise ComplexError("这是一个自定义异常", 500)
except ComplexError as e:
    print(e)
结果为:
这个是自定义异常
Error Code 500: 这是一个自定义异常

三、模块与包

3.1 模块 (Module)

模块是一个包含 Python 定义和语句的文件,文件名就是模块名加上 .py 扩展名。模块可以定义函数、类和变量,也能包含可执行的代码。通过导入模块,你可以在其他 Python 程序里复用这些定义和代码。

模块导入方式

导入方式 (import modulefrom module import func)

  • import 模块名 :导入整个模块,使用模块内的函数、类或变量时需加上模块名作为前缀。
  • from 模块名 import 函数名/类名/变量名 :从模块中导入指定的函数、类或变量,使用时无需加模块名前缀。
  • from 模块名 import * :导入模块中的所有内容,使用时无需加模块名前缀,但不建议使用,可能会导致命名冲突。
import sys
# 打印 Python 解释器的版本信息
print("Python 版本信息:", sys.version)
# 退出程序
# sys.exit(0)  # 取消注释可退出程序
结果为:
Python 版本信息: 3.10.10 (tags/v3.10.10:aad5f6a, Feb  7 2023, 17:20:36)
模块搜索路径
  • Python 按 sys.path 列表查找模块。
print("sys.path 内容:", sys.path)
# 添加新的模块搜索路径
new_path = "D:\\"
sys.path.append(new_path)
__name__ 属性的作用

__name__ 是一个内置的特殊变量,其作用主要体现在区分代码是作为脚本直接运行,还是作为模块被导入。

  • 当模块作为脚本运行时,if __name__"__main__"。利用这个特性,能够让部分代码仅在脚本直接运行时执行。
  • 作为模块导入时为模块名。if __name__ == '__main__': 代码块内的代码不会执行

3.2 包 (Package)

包是一种管理 Python 模块命名空间的方式,它是一个包含多个模块的目录。目录下必须包含一个 __init__.py 文件(Python 3.3 之后, __init__.py 文件不是强制要求,但为了兼容性,建议保留),该文件可以为空,也能包含 Python 代码,用于初始化包。

包的结构
  • 包含 __init__.py 文件的目录。

导入方式

  • import 包名.模块名 :导入包中的指定模块,使用模块内的内容时需加上完整前缀。
  • from 包名 import 模块名 :从包中导入指定模块,使用模块内的内容时需加上模块名前缀。
  • from 包名.模块名 import 函数名/类名/变量名 :从包中的指定模块导入特定内容,使用时无需加前缀。
# 1. 导入标准库
# 导入整个 math 库
import math
# 使用 math 库中的函数,需要加库前缀
result = math.sqrt(16)
print("16 的平方根是:", result)

# 2. 导入库中的特定函数或类
# 从 random 库中导入 randint 函数
from random import randint
# 使用导入的函数,不需要加库的前缀
random_num = randint(1, 10)
print("1 到 10 之间的随机整数是:", random_num)

# 3. 导入库并使用别名
# 导入 pandas 库并起别名 pd
import pandas as pd
# 使用别名创建一个简单的 DataFrame
data = {'Name': ['张三', '李四'], 'Age': [25, 30]}
df = pd.DataFrame(data)
print(df)
结果为:
16 的平方根是: 4.0
1 到 10 之间的随机整数是: 4
  Name  Age
0   张三   25
1   李四   30
__init__.py 文件的作用
  • 初始化包,可控制包导入行为。
    从 Python 3.3 开始, __init__.py 文件不再是必需的,Python 会自动将包含模块的目录视为命名空间包。
  1. 初始化代码 :可以在 __init__.py 中编写初始化代码,这些代码会在包被导入时执行。
  2. 控制导入内容 :使用__all__变量来控制使用 from package import * 语句时导入的模块或函数。
发布自己的包
  • 需创建 setup.py 文件,使用 setuptools 打包。

四、高级特性

4.1 迭代器与生成器

迭代器
  • 实现 __iter__()__next__() 方法的对象,适用于需要自定义复杂迭代逻辑的场景。
    __iter__() 方法返回迭代器对象本身,__next__()方法返回迭代的下一个值,当没有更多元素时抛出 StopIteration 异常。
class 迭代器类名:
    def __init__(self, 参数):
        # 初始化代码

      def __iter__(self):
        return self

    def __next__(self):
        # 实现迭代逻辑
        if 没有更多元素:
            raise StopIteration
        return 下一个值
# 自定义迭代器类,用于生成 0 到 n-1 的整数
class MyIterator:
    def __init__(self, n):
        self.n = n
        self.current = 0

    def __iter__(self):
        return self

    def __next__(self):
        if self.current < self.n:
            result = self.current
            self.current += 1
            return result
        else:
            raise StopIteration

# 使用自定义迭代器
my_iter = MyIterator(5)
for num in my_iter:
    print(num) # 输出 0, 1, 2, 3, 4

# 内置可迭代对象转换为迭代器
my_list = [1, 2, 3]
iter_obj = iter(my_list)
print(next(iter_obj))  # 输出 1
print(next(iter_obj))  # 输出 2
print(next(iter_obj))  # 输出 3
生成器
  • 用函数和 yield 关键字创建,或使用生成器表达式。

生成器是一种特殊的迭代器,它分为生成器函数和生成器表达式。
生成器函数使用 yield 关键字,每次调用 next() 时会执行到 yield 处并返回值,下次调用会从暂停的地方继续执行。
生成器表达式则类似于列表推导式,使用圆括号。

# 生成器函数,用于生成 0 到 n-1 的整数
def my_generator(n):
    current = 0
    while current < n:
        yield current
        current += 1

# 使用生成器函数
gen = my_generator(5)
for num in gen:
    print(num)

# 生成器表达式
gen_expr = (x * 2 for x in range(5))
for num in gen_expr:
    print(num)
结果为:
0
1
2
3
4

0
2
4
6
8
生成器的优势
  • 节省内存,按需生成数据。

4.2 装饰器

装饰器是一种强大且实用的设计模式,它允许你在不修改原有函数代码的基础上,对函数的功能进行扩展。
装饰器是一种特殊的函数或者类,这个函数接收一个函数作为参数,并且返回一个新的函数。
在函数定义时,使用 @ 符号加上装饰器名称,就可以将装饰器应用到该函数上。
通过这种方式,我们可以在调用原函数前后添加额外的逻辑,比如日志记录、性能测试、权限验证等。

装饰器原理
  • 用于修改函数或类的行为。

Python 装饰器的实现基于两个重要的特性:函数是一等公民和闭包。

函数是一等公民:在 Python 中,函数可以像变量一样被传递、赋值、作为参数和返回值。这意味着我们可以将一个函数作为另一个函数的参数,并且可以从函数中返回另一个函数。
闭包:闭包是指在一个函数内部定义另一个函数,并且内部函数可以访问外部函数的局部变量。当外部函数返回内部函数时,这些局部变量会被保留下来,供内部函数后续使用。

无参数装饰器

无参数装饰器是最基本的装饰器形式,它接收一个函数作为参数,并返回一个新的函数。

# 定义装饰器函数
def my_decorator(func):
    # 定义内部函数 wrapper,它是一个闭包
    def wrapper():
        print("Before function")
        # 调用传入的原函数
        func()
        print("After function")
    # 返回内部函数 wrapper
    return wrapper

# 使用装饰器
@my_decorator
def say_hello():
    print("Hello")

# 调用被装饰后的函数
say_hello()
  • 定义装饰器函数 : my_decorator 是一个装饰器函数,它接收一个函数 func 作为参数。
  • 定义内部函数 wrapper : wrapper 是一个闭包,它可以访问外部函数 my_decorator 的参数 func 。在 wrapper 函数内部,我们可以在调用原函数 func 前后添加额外的逻辑。
  • 返回内部函数 : my_decorator 函数返回 wrapper 函数,这样当我们使用装饰器时,原函数就会被替换为 wrapper 函数。
  • 使用装饰器 : @my_decorator 语法糖等价于 say_hello = my_decorator(say_hello) ,这意味着 say_hello 现在指向的是 my_decorator 返回的 wrapper 函数。
  • 调用被装饰后的函数 :当我们调用 say_hello() 时,实际上调用的是 wrapper() 函数,从而执行了额外的逻辑和原函数的逻辑。
结果为:
Before function
Hello
After function
带参数装饰器需多一层函数嵌套

带参数装饰器比无参数装饰器更灵活,它可以接收额外的参数。通常需要在无参数装饰器的基础上再嵌套一层函数。

# 定义带参数的装饰器
def repeat(num):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for _ in range(num):
                result = func(*args, **kwargs)
            return result
        return wrapper
    return decorator

# 使用带参数的装饰器
@repeat(3)
def greet(name):
    print(f"Hello, {name}!")

# 调用被装饰后的函数
greet("张三")

repeat 是一个带参数的装饰器,它接收一个整数 num 作为参数。 repeat 函数返回一个无参数装饰器 decorator , decorator 函数返回 wrapper 函数。当调用 greet(“张三”) 时, greet 函数会被执行 3 次。

结果为:
Hello, 张三!
Hello, 张三!
Hello, 张三!
类装饰器

类装饰器是使用类来实现的装饰器,通常需要在类中实现 __call__ 方法。

# 定义类装饰器
class CountCalls:
    def __init__(self, func):
        self.func = func
        self.num_calls = 0

    def __call__(self, *args, **kwargs):
        self.num_calls += 1
        print(f"Call {self.num_calls} of {self.func.__name__}")
        return self.func(*args, **kwargs)

# 使用类装饰器
@CountCalls
def add(a, b):
    return a + b

# 调用被装饰后的函数
print(add(2, 3))
print(add(4, 5))

add = CountCalls(add) 这行代码创建了一个 CountCalls 类的实例,并且把 add 函数作为参数传递给 __init__ 方法。之后,每次调用 add 函数时,实际上调用的是 CountCalls 实例的 __call__ 方法。在 __call__ 方法里,会记录函数的调用次数并打印相关信息,然后再调用原始的 add 函数。

结果为:
Call 1 of add
5
Call 2 of add
9

4.3 并发编程

多线程

threading 模块可用于实现多线程编程,它提供了创建和管理线程的类和方法。

  • 使用 threading 模块,如:
import threading

# 定义一个简单的函数,作为线程执行的任务
def print_numbers():
    for i in range(5):
        print(f"Thread 1: {i}")

def print_letters():
    for letter in 'abcde':
        print(f"Thread 2: {letter}")

# 创建线程对象
thread1 = threading.Thread(target=print_numbers)
thread2 = threading.Thread(target=print_letters)

# 启动线程
thread1.start()
thread2.start()

# 等待线程执行完毕
thread1.join()
thread2.join()

print("All threads have finished.")
结果为:
Thread 1: 0
Thread 1: 1
Thread 2: a
Thread 1: 2
Thread 1: 3
Thread 2: b
Thread 1: 4
Thread 2: c
Thread 2: d
Thread 2: e
All threads have finished.
  • 使用线程类
    通过继承 threading.Thread 类,重写 run() 方法来创建自定义线程。
import threading

# 自定义线程类
class MyThread(threading.Thread):
    def __init__(self, name, times):
        super().__init__()
        self.name = name
        self.times = times

    def run(self):
        for _ in range(self.times):
            print(f"Custom Thread: {self.name}!")

# 创建线程对象
thread5 = MyThread("张三", 4)
thread6 = MyThread("李四", 3)

# 启动线程
thread5.start()
thread6.start()

# 等待线程执行完毕
thread5.join()
thread6.join()

print("Custom threads have finished.")

继承 threading.Thread 类,在__init__方法中初始化线程,重写 run() 方法定义线程要执行的任务。
调用 start() 方法启动线程时,会自动调用 run() 方法。

结果为:
Custom Thread: 张三!
Custom Thread: 张三!
Custom Thread: 张三!
Custom Thread: 张三!
Custom Thread: 李四!
Custom Thread: 李四!
Custom Thread: 李四!
Custom threads have finished.
多进程
  • 使用 multiprocessing 模块,可充分利用多核 CPU。
import multiprocessing
import os

def worker(num):
    """子进程要执行的任务"""
    print(f'子进程 {num} PID: {os.getpid()}')
    return num * num

if __name__ == '__main__':
    # 创建4个子进程
    processes = []
    for i in range(4):
        p = multiprocessing.Process(target=worker, args=(i,))
        processes.append(p)
        p.start()

    # 等待所有子进程完成
    for p in processes:
        p.join()

    # 使用进程池
    with multiprocessing.Pool(processes=4) as pool:
        results = pool.map(worker, range(10))
        print(f'进程池计算结果: {results}')
结果为:
子进程 0 PID: 15632
子进程 1 PID: 13048
子进程 2 PID: 22896
子进程 3 PID: 14816
子进程 0 PID: 22328
子进程 1 PID: 22328
子进程 2 PID: 22328
子进程 3 PID: 22328
子进程 4 PID: 22328
子进程 5 PID: 22328
子进程 6 PID: 22328
子进程 7 PID: 22328
子进程 8 PID: 11896
子进程 9 PID: 22328
进程池计算结果: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
异步编程
  • 使用 asyncio 模块。通过 asyncawait 关键字实现异步操作。

asyncio 是 Python 中用于编写单线程并发代码的库,借助 async 和 await 关键字,能实现高效的异步操作。

import asyncio

# 定义一个异步函数
async def hello_world():
    print("开始执行异步任务")
    # 模拟一个耗时操作,比如网络请求或文件读写
    await asyncio.sleep(1)
    print("异步任务执行完毕")

async def main():
    # 调用异步函数
    await hello_world()

if __name__ == "__main__":
    # 运行异步程序
    asyncio.run(main())

async def :用于定义异步函数,异步函数内部可使用 await 关键字。
await :用于暂停异步函数的执行,直到等待的协程完成。
asyncio.sleep(1) :模拟一个耗时 1 秒的操作。
asyncio.run(main()) :用于运行异步程序的入口点。

结果为:
开始执行异步任务
异步任务执行完毕
  • 并发执行多个异步任务
import asyncio

async def task1():
    print("任务 1 开始")
    await asyncio.sleep(2)
    print("任务 1 结束")

async def task2():
    print("任务 2 开始")
    await asyncio.sleep(1)
    print("任务 2 结束")

async def main():
    # 创建任务列表
    tasks = [task1(), task2()]
    # 并发执行多个任务
    await asyncio.gather(*tasks)

if __name__ == "__main__":
    asyncio.run(main())

asyncio.gather(*tasks) :用于并发执行多个异步任务,会等待所有任务完成后才会继续执行后续代码。

任务 1 开始
任务 2 开始
任务 2 结束
任务 1 结束
  • 异步任务返回值
import asyncio

async def add(a, b):
    await asyncio.sleep(1)
    return a + b

async def main():
    # 并发执行多个异步任务并获取返回值
    results = await asyncio.gather(add(1, 2), add(3, 4))
    print(results)

if __name__ == "__main__":
    asyncio.run(main())
结果为:
任务 1 开始
任务 2 开始
任务 2 结束
任务 1 结束
异步任务的返回值
[3, 7]

五、Python 应用领域

5.1 数据分析

  • numpy:用于高效的数值计算。
  • pandas:用于数据处理和分析。
  • matplotlib:用于数据可视化。

5.2 Web 开发

Flask 框架
  • 轻量级 Web 框架,易于上手。默认属于同步框架,处理并发请求时能力有限。可以通过Flask-Async等扩展来支持异步,使用起来相对复杂。
Django 框架

Django 是一个高级 Python Web 框架,遵循 MVC(实际上是 MTV,即 Model - Template - View)架构模式,强调快速开发和代码复用。

  • 功能强大的 Web 框架,自带管理后台等功能。
FastAPI框架

FastAPI 是一个用于构建 API 的现代、快速(高性能)的 Python Web 框架,它基于 Python 的类型提示和 Starlette、Pydantic 库。

特点

  • 快速:性能与 NodeJS 和 Go 相当,得益于使用了 Python 的异步编程能力。
  • 易于使用:基于类型提示来定义 API 的输入和输出,使得代码具有良好的可读性和可维护性。
  • 高效开发:自动生成交互式 API 文档(如 Swagger UI 和 ReDoc),便于测试和调试。
  • 类型检查:利用 Python 的类型提示进行输入验证和数据序列化,减少运行时错误。

5.3 机器学习

  • scikit-learn:提供多种机器学习算法。
  • tensorflow:用于深度学习。
  • pytorch:深度学习框架,易用且灵活。

5.4 自然语言处理

  • NLTK - 自然语言工具包
  • spaCy - 工业级NLP库
  • Transformers - HuggingFace的Transformer模型库

5.5 计算机视觉

  • OpenCV - 计算机视觉库
  • PIL/Pillow - 图像处理库

5.6 模型部署

  • ONNX - 模型交换格式
  • TensorRT - NVIDIA的推理优化器
  • FastAPI - 构建API服务的框架

5.7 爬虫开发

  • requests:用于发送 HTTP 请求。
  • BeautifulSoup:用于解析 HTML 和 XML 文档。
  • Scrapy 框架:用于高效的爬虫开发。