Python with语句常见错误AttributeError: __enter__

连接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()
  • 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?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值