连接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()
__enter__
错误解决