Python中如何解决try-catch块内变量无法跨文件导入的问题
问题根因与解决方案
错误根本原因
- 变量未定义:
cursor仅在try块数据库连接成功时才会被创建,若连接触发异常进入except分支,该变量不会在模块全局命名空间生成,导入时自然找不到对应名称。 - 连接提前失效:即使连接成功,else分支会立刻执行
cnx.close(),此时就算能导入cursor,其关联的数据库连接已经被关闭,也无法执行任何SQL操作。 - 你猜测的异步对象原因不成立,当前代码为同步MySQL连接逻辑,和异步对象无关。
修复方案
推荐将数据库连接逻辑封装为可复用的工具函数/上下文管理器,按需创建连接和游标,使用完成后自动释放资源,避免连接泄漏。
修改后的database.py代码
import mysql.connector from mysql.connector import errorcode # 数据库配置参数 DB_CONFIG = { "user": database_username, "password": database_password, "host": database_hostname, "database": database_name } def get_db_cursor(): """获取数据库连接和游标,使用完成后需手动关闭连接""" try: cnx = mysql.connector.connect(**DB_CONFIG) cursor = cnx.cursor() return cnx, cursor except mysql.connector.Error as err: if err.errno == errorcode.ER_ACCESS_DENIED_ERROR: raise RuntimeError("用户名或密码错误") from err elif err.errno == errorcode.ER_BAD_DB_ERROR: raise RuntimeError("数据库不存在") from err else: raise RuntimeError(f"数据库连接失败: {err}") from err # 更推荐的上下文管理器写法,自动释放资源、处理事务 def db_operation(): cnx = None try: cnx = mysql.connector.connect(**DB_CONFIG) cursor = cnx.cursor() yield cursor cnx.commit() except mysql.connector.Error as err: if cnx: cnx.rollback() if err.errno == errorcode.ER_ACCESS_DENIED_ERROR: raise RuntimeError("用户名或密码错误") from err elif err.errno == errorcode.ER_BAD_DB_ERROR: raise RuntimeError("数据库不存在") from err else: raise RuntimeError(f"数据库操作失败: {err}") from err finally: if cnx: cnx.close()
其他文件使用示例
from database import get_db_cursor, db_operation # 方式1:手动管理连接 cnx, cursor = get_db_cursor() try: cursor.execute("SELECT * FROM 你的表名 LIMIT 1") print(cursor.fetchall()) finally: cursor.close() cnx.close() # 方式2:上下文管理器自动管理(更推荐,无需手动关连接、处理事务) with db_operation() as cursor: cursor.execute("SELECT * FROM 你的表名 LIMIT 1") print(cursor.fetchall())
内容的提问来源于stack exchange,提问作者Hussein Al-Mosawi
相关产品推荐
相关产品推荐

