Python 上下文管理器的 3 个有趣用途 - KDnuggets

Python 上下文管理器的 3 个有趣用途 – KDnuggets

源节点: 3084989

Python 上下文管理器的 3 个有趣用途
图片由 johnstocker 提供 Freepik
 

前段时间我写了一篇教程 编写高效的Python代码。在其中,我讨论了使用上下文管理器和 with 语句来有效地管理资源。

我使用一个简单的文件处理示例来展示当执行退出 with 块时如何自动关闭文件 - 即使存在异常。

虽然文件处理是一个很好的第一个例子,但它很快就会变得无聊。这就是为什么我想在本教程中介绍上下文管理器的其他有趣用途(除了文件处理之外)。我们将重点关注处理数据库连接、管理子进程和高精度浮点运算。

Python 中的上下文管理器允许您在使用资源时编写更清晰的代码。它们提供了一种简洁的语法来通过以下方式设置和拆除资源:

  • An 进入 当执行进入上下文时调用的逻辑
  • An 出口 当执行退出上下文时调用的逻辑 

最简单的例子是文件处理。这里我们使用 open() 函数在 with 获取文件处理程序的语句:

with open('filename.txt', 'w') as file:
    file.write('Something random')

 

这将获取代码块中使用(我们写入文件)的资源(文件对象)。一旦执行退出上下文,文件就会关闭;所以不存在资源泄漏。

您可以像这样编写通用版本:

with some_context() as ctx:
    # do something useful on the resource!

# resource cleanup is automatic

 

现在我们继续看具体的例子。

当您构建 Python 应用程序时,连接到数据库并查询其中包含的表是很常见的。执行此操作的工作流程如下所示:

  • 安装数据库连接器以使用数据库(例如用于 Postgres 的 psycopg2 和用于 MySQL 数据库的 mysql-connector-python)。
  • 解析配置文件以检索连接参数。 
  • 使用 connect() 函数建立与数据库的连接。

 

Python 上下文管理器的 3 个有趣用途
连接到数据库|作者提供的图片
 

连接到数据库后,您可以创建数据库来查询数据库。使用 run 和 fetch 游标方法运行查询并获取查询结果。

 

Python 上下文管理器的 3 个有趣用途
查询数据库 |作者提供的图片
 

在此过程中,您将创建以下资源:数据库连接和数据库游标。现在让我们编写一个简单的通用示例,看看如何使用连接和游标对象作为上下文管理器。

在 Python 中解析 TOML 文件

考虑一个示例 TOML 文件,例如 db_config.toml,其中包含连接到数据库所需的信息:

# db_config.toml

[database]
host = "localhost"
port = 5432
database_name = "your_database_name"
user = "your_username"
password = "your_password"

 

备注:需要Python 3.11或更高版本才能使用 托姆利库.

 

Python 有一个内置的 托姆利库 模块(在 Python 3.11 中引入)可让您解析 TOML 文件。因此,您可以打开 db_config.toml 文件并解析其内容,如下所示:

import tomllib

with open('db_config.toml','rb') as file:
	credentials = tomllib.load(file)['database']

 

请注意,我们进入了 db_config.toml 文件的“数据库”部分。这 load() 函数返回一个 Python 字典。您可以通过打印出以下内容来验证这一点 credentials:

print(credentials)

 

Output >>>
{'host': 'localhost', 'port': 5432, 'database_name': 'your_database_name', 'user': 'your_username', 'password': 'your_password'}

连接到数据库

假设您要连接到 Postgres 数据库。您可以安装 psycopg2 连接器 使用点:

pip install psycopg2

 

您可以在 with 语句中使用连接和游标对象,如下所示:

import psycopg2

# Connect to the database
with psycopg2.connect(**credentials) as conn:
	# Inside this context, the connection is open and managed

	with conn.cursor() as cur:
    	# Inside this context, the cursor is open and managed

    	cur.execute('SELECT * FROM my_table')
    	result = cur.fetchall()
            print(result)

 

在这段代码中:

  • 我们使用 with 语句创建用于管理数据库连接的上下文。 
  • 在这个上下文中,我们创建另一个上下文来管理数据库游标。退出此内部上下文时,光标会自动关闭。
  • 由于退出外部上下文时连接也会关闭,因此此构造可确保连接和游标都得到正确管理,从而减少资源泄漏的机会。

使用 SQLite 和 MySQL 数据库时也可以使用类似的构造。

Python 的 subprocess 模块提供了在 Python 脚本内运行外部命令的功能。这 subprocess.Popen() 构造函数创建一个新的子进程。您可以在 with 像这样的声明:

import subprocess

# Run an external command and capture its output
with subprocess.Popen(['ls', '-l'], stdout=subprocess.PIPE, text=True) as process:
	output, _ = process.communicate()
	print(output)

 

在这里,我们运行 Bash 命令 ls -l 命令长列出当前目录中的文件:

Output >>>

total 4
-rw-rw-r-- 1 balapriya balapriya   0 Jan  5 18:31 db_info.toml
-rw-rw-r-- 1 balapriya balapriya 267 Jan  5 18:32 main.py

 

一旦执行退出上下文,与子进程关联的资源就会被释放 with 语句。 

Python内置的float数据类型不适合高精度浮点运算。但在处理财务数据、传感器读数等时,您确实需要高精度。对于此类应用程序,您可以使用 十进制 模块代替。 

localcontext() 功能 返回一个上下文管理器。所以你可以使用 localcontext() 函数在 with 语句,并使用如下所示设置当前上下文的精度:

from decimal import Decimal, localcontext

with localcontext() as cur_context:
    cur_context.prec = 40
    a = Decimal(2)
    b = Decimal(3)
    print(a/b)

 

这是输出:

Output >>>
0.6666666666666666666666666666666666666667

 

此处,精度设置为小数点后 40 位,但仅在此范围内 with 堵塞。当执行退出当前上下文时,精度将恢复为默认精度(28 位小数)。

在本教程中,我们学习了如何使用上下文管理器来处理数据库连接、管理高精度浮点运算中的子进程和上下文。

在下一个教程中,我们将了解如何在 Python 中创建自定义上下文管理器。在那之前,祝您编码愉快!
 
 

巴拉普里亚 C 是来自印度的开发人员和技术作家。 她喜欢在数学、编程、数据科学和内容创作的交叉领域工作。 她的兴趣和专长领域包括 DevOps、数据科学和自然语言处理。 她喜欢阅读、写作、编码和咖啡! 目前,她致力于通过编写教程、操作指南、评论文章等方式学习并与开发人员社区分享她的知识。

时间戳记:

更多来自 掘金队