Python with语句常见错误AttributeError: __enter__

连接MySQL过程中,

with con:
    cur = con.cursor()
    cur.executemany(final_str, symbols)

出现如下错误:
Python with语句常见错误AttributeError: __enter___第1张图片

关乎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()
  • Reference

  1. 浅谈 Python 的 with 语句
  2. tensorflow报AttributeError: __enter__错误解决
  3. Getting “AttributeError: enter” when using pymysql in pycharm
  4. Python上下文管理器与with语句
  5. Remove context interface from Connector (#295)
  6. Context manager for Python’s MySQLdb
  7. Can I use with statement with MySQLdb.Connection object?

你可能感兴趣的:(#,Python)