连接MySQL过程中,
with con:
cur = con.cursor()
cur.executemany(final_str, symbols)
出现如下错误:
关乎with语句的用法中上下文管理器。
上下文管理器必须同时提供 __enter__() 和 __exit__() 方法的定义,缺少任何一个都会导致 AttributeError;with 语句会先检查是否提供了 __exit__() 方法,然后检查是否定义了 __enter__() 方法。
AttributeError指的是属性错误,就是说con这个对象没有__enter__属性,不能用在with语句中,确切的说是不能用于 context managers(上下文管理器)。
With 语句仅能工作于支持上下文管理协议(context management protocol)的对象。也就是说只有内建了”上下文管理”的对象才能和 with 一起工作。Python内置了一些支持该协议的对象,如下所列是一个简短列表:
-
file
-
decimal.Context
-
thread.LockType
-
threading.Lock
-
threading.RLock
-
threading.Condition
-
threading.Semaphore
-
threading.BoundedSemaphore
-
with connect
-
原因解释
MySQLdb/connections.py以前是有上下文协议的,2018.12.4去掉了。
Remove context interface from Connector (#295)
def __enter__(self):
from warnings import warn
warn("context interface will be changed. Use explicit conn.commit() or conn.rollback().",
DeprecationWarning, 2)
if self.get_autocommit():
self.query("BEGIN")
return self.cursor()
def __exit__(self, exc, value, tb):
if exc:
self.rollback()
else:
self.commit()
自己写一个上下文对象:
import MySQLdb as mdb
import MySQLdb.cursors as mc
import contextlib
DictCursor = mc.DictCursor
SSCursor = mc.SSCursor
SSDictCursor = mc.SSDictCursor
Cursor = mc.Cursor
@contextlib.contextmanager
def connection(cursorclass=Cursor,
host='localhost', user='root',
passwd='---', dbname='---',
driver=mdb):
connection = driver.connect(
host=host, user=user, passwd=passwd, db=dbname,
cursorclass=cursorclass)
try:
yield connection
except Exception:
connection.rollback()
raise
else:
connection.commit()
finally:
connection.close()
本文探讨了在使用Python连接MySQL数据库时遇到的AttributeError问题,详细解释了上下文管理器的概念及其在with语句中的作用。由于MySQLdb库在更新后移除了上下文接口,文章提供了自定义上下文管理器的解决方案,确保代码的正常运行。
1349

被折叠的 条评论
为什么被折叠?



