为什么在Python3.5中使用asyncio时被忽略了异常

为什么在Python3.5中使用asyncio时被忽略了异常,python,python-3.x,coroutine,python-asyncio,Python,Python 3.x,Coroutine,Python Asyncio,信息: python 3.5 使用submizerepl运行代码 阿西尼奥 异常回溯如下所示 Exception ignored in: <bound method Connection.__del__ of <aiomysql.connection.Connection object at 0x00000030F8080B38>> Traceback (most recent call last): File "C:\software\development\p

信息:

  • python 3.5
  • 使用submizerepl运行代码
  • 阿西尼奥
异常回溯如下所示

Exception ignored in: <bound method Connection.__del__ of <aiomysql.connection.Connection object at 0x00000030F8080B38>>
Traceback (most recent call last):
  File "C:\software\development\python3.5\lib\site-packages\aiomysql\connection.py", line 689, in __del__
  File "C:\software\development\python3.5\lib\site-packages\aiomysql\connection.py", line 261, in close
  File "C:\software\development\python3.5\lib\asyncio\selector_events.py", line 569, in close
  File "C:\software\development\python3.5\lib\asyncio\base_events.py", line 447, in call_soon
  File "C:\software\development\python3.5\lib\asyncio\base_events.py", line 456, in _call_soon
  File "C:\software\development\python3.5\lib\asyncio\base_events.py", line 284, in _check_closed
RuntimeError: Event loop is closed
from models import User
import asyncio
import sys
import orm
import pdb
import time

# import pdb

# 测试插入


@asyncio.coroutine
def test_save(loop):
    yield from orm.create_pool(loop, user='kami', password='kami', db='pure_blog')
    u = User(name='hi', email='hi@example.com',
             passwd='hi', image='about:blank')
    # pdb.set_trace()
    yield from u.save()

# 测试查询


@asyncio.coroutine
def test_findAll(loop):
    yield from orm.create_pool(loop, user='kami', password='kami', db='pure_blog')
    # 这里给的关键字参数按照xxx='xxx'的形式给出,会自动分装成dict
    rs = yield from User.findAll(email='test@example.com')      # rs是一个元素为dict的list
    # pdb.set_trace()
    for i in range(len(rs)):
        print(rs[i])

# 查询条数?


@asyncio.coroutine
def test_findNumber(loop):
    yield from orm.create_pool(loop, user='kami', password='kami', db='pure_blog')
    count = yield from User.findNumber('email')
    print(count)

# 根据主键查找,这里试ID


@asyncio.coroutine
def test_find_by_key(loop):
    yield from orm.create_pool(loop, user='kami', password='kami', db='pure_blog')
    # rs是一个dict
    # ID请自己通过数据库查询
    rs = yield from User.find_by_key('0014531826762080b29033a78624bc68c867550778f64d6000')
    print(rs)

# 根据主键删除


@asyncio.coroutine
def test_remove(loop):
    yield from orm.create_pool(loop, user='kami', password='kami', db='pure_blog')
    # 用id初始化一个实例对象
    u = User(id='0014531826762080b29033a78624bc68c867550778f64d6000')
    yield from u.remove()


# 根据主键更新
@asyncio.coroutine
def test_update(loop):
    yield from orm.create_pool(loop, user='kami', password='kami', db='pure_blog')
    # 必须按照列的顺序来初始化:'update `users` set `created_at`=?, `passwd`=?, `image`=?,
    # `admin`=?, `name`=?, `email`=? where `id`=?' 注意这里要使用time()方法,否则会直接返回个时间戳对象,而不是float值
    u = User(id='00145318300622886f186530ee74afabecedb42f9cd590a000', created_at=time.time(), passwd='test',
             image='about:blank', admin=True, name='test', email='hello1@example.com')  # id必须和数据库一直,其他属性可以设置成新的值,属性要全
    # pdb.set_trace()
    yield from u.update()


loop = asyncio.get_event_loop()  # 获取消息循环对象
loop.run_until_complete(test_update(loop))  # 执行协程
loop.close()
测试文件如下所示

Exception ignored in: <bound method Connection.__del__ of <aiomysql.connection.Connection object at 0x00000030F8080B38>>
Traceback (most recent call last):
  File "C:\software\development\python3.5\lib\site-packages\aiomysql\connection.py", line 689, in __del__
  File "C:\software\development\python3.5\lib\site-packages\aiomysql\connection.py", line 261, in close
  File "C:\software\development\python3.5\lib\asyncio\selector_events.py", line 569, in close
  File "C:\software\development\python3.5\lib\asyncio\base_events.py", line 447, in call_soon
  File "C:\software\development\python3.5\lib\asyncio\base_events.py", line 456, in _call_soon
  File "C:\software\development\python3.5\lib\asyncio\base_events.py", line 284, in _check_closed
RuntimeError: Event loop is closed
from models import User
import asyncio
import sys
import orm
import pdb
import time

# import pdb

# 测试插入


@asyncio.coroutine
def test_save(loop):
    yield from orm.create_pool(loop, user='kami', password='kami', db='pure_blog')
    u = User(name='hi', email='hi@example.com',
             passwd='hi', image='about:blank')
    # pdb.set_trace()
    yield from u.save()

# 测试查询


@asyncio.coroutine
def test_findAll(loop):
    yield from orm.create_pool(loop, user='kami', password='kami', db='pure_blog')
    # 这里给的关键字参数按照xxx='xxx'的形式给出,会自动分装成dict
    rs = yield from User.findAll(email='test@example.com')      # rs是一个元素为dict的list
    # pdb.set_trace()
    for i in range(len(rs)):
        print(rs[i])

# 查询条数?


@asyncio.coroutine
def test_findNumber(loop):
    yield from orm.create_pool(loop, user='kami', password='kami', db='pure_blog')
    count = yield from User.findNumber('email')
    print(count)

# 根据主键查找,这里试ID


@asyncio.coroutine
def test_find_by_key(loop):
    yield from orm.create_pool(loop, user='kami', password='kami', db='pure_blog')
    # rs是一个dict
    # ID请自己通过数据库查询
    rs = yield from User.find_by_key('0014531826762080b29033a78624bc68c867550778f64d6000')
    print(rs)

# 根据主键删除


@asyncio.coroutine
def test_remove(loop):
    yield from orm.create_pool(loop, user='kami', password='kami', db='pure_blog')
    # 用id初始化一个实例对象
    u = User(id='0014531826762080b29033a78624bc68c867550778f64d6000')
    yield from u.remove()


# 根据主键更新
@asyncio.coroutine
def test_update(loop):
    yield from orm.create_pool(loop, user='kami', password='kami', db='pure_blog')
    # 必须按照列的顺序来初始化:'update `users` set `created_at`=?, `passwd`=?, `image`=?,
    # `admin`=?, `name`=?, `email`=? where `id`=?' 注意这里要使用time()方法,否则会直接返回个时间戳对象,而不是float值
    u = User(id='00145318300622886f186530ee74afabecedb42f9cd590a000', created_at=time.time(), passwd='test',
             image='about:blank', admin=True, name='test', email='hello1@example.com')  # id必须和数据库一直,其他属性可以设置成新的值,属性要全
    # pdb.set_trace()
    yield from u.update()


loop = asyncio.get_event_loop()  # 获取消息循环对象
loop.run_until_complete(test_update(loop))  # 执行协程
loop.close()
我尝试将“run_until_complete”方法放入一个协同程序(请参阅本文末尾的execute_测试方法),它似乎起到了作用。但我还是不知道为什么

from models import User
import asyncio
import sys
import orm
import pdb
import time

# import pdb

# 测试插入


@asyncio.coroutine
def test_save(loop):
    yield from orm.create_pool(loop, user='kami', password='kami', db='pure_blog')
    u = User(name='hi', email='hi@example.com',
             passwd='hi', image='about:blank')
    # pdb.set_trace()
    yield from u.save()

# 测试查询


@asyncio.coroutine
def test_findAll(loop):
    yield from orm.create_pool(loop, user='kami', password='kami', db='pure_blog')
    # 这里给的关键字参数按照xxx='xxx'的形式给出,会自动分装成dict
    rs = yield from User.findAll(email='test@example.com')      # rs是一个元素为dict的list
    # pdb.set_trace()
    for i in range(len(rs)):
        print(rs[i])

# 查询条数?


@asyncio.coroutine
def test_findNumber(loop):
    yield from orm.create_pool(loop, user='kami', password='kami', db='pure_blog')
    count = yield from User.findNumber('email')
    print(count)

# 根据主键查找,这里试ID


@asyncio.coroutine
def test_find_by_key(loop):
    yield from orm.create_pool(loop, user='kami', password='kami', db='pure_blog')
    # rs是一个dict
    # ID请自己通过数据库查询
    rs = yield from User.find_by_key('0014531826762080b29033a78624bc68c867550778f64d6000')
    print(rs)

# 根据主键删除


@asyncio.coroutine
def test_remove(loop):
    yield from orm.create_pool(loop, user='kami', password='kami', db='pure_blog')
    # 用id初始化一个实例对象
    u = User(id='0014531826762080b29033a78624bc68c867550778f64d6000')
    yield from u.remove()


# 根据主键更新
@asyncio.coroutine
def test_update(loop):
    yield from orm.create_pool(loop, user='kami', password='kami', db='pure_blog')
    # 必须按照列的顺序来初始化:'update `users` set `created_at`=?, `passwd`=?, `image`=?,
    # `admin`=?, `name`=?, `email`=? where `id`=?' 注意这里要使用time()方法,否则会直接返回个时间戳对象,而不是float值
    u = User(id='00145318300622886f186530ee74afabecedb42f9cd590a000', created_at=time.time(), passwd='test',
             image='about:blank', admin=True, name='test', email='hello1@example.com')  # id必须和数据库一直,其他属性可以设置成新的值,属性要全
    # pdb.set_trace()
    yield from u.update()


@asyncio.coroutine
def execute_test(loop):
    yield from loop.run_until_complete(test_update(loop))  # 执行协程
    yield from loop.close()


loop = asyncio.get_event_loop()  # 获取消息循环对象
execute_test(loop)

在关闭事件循环之前,您需要关闭连接池,请参阅

就你而言:

loop = asyncio.get_event_loop()
loop.run_until_complete(test_update(loop))
__pool.close()
loop.run_until_complete(__pool.wait_closed())
loop.close()

如何运行测试?在显式
loop.close()
调用之前,应该显式关闭AIMYSQL连接(也许您的ORM需要一个池)。@dirn我在sublime中使用了一个名为SublimeREPL的插件。它的工作原理与使用命令“python orm_test.py”相同。我使用test_update方法通过create_pool方法(使用aimysql lib)创建连接池。然后,我初始化一个用户对象,并用update方法将其保存到数据库中。我认为Andrew Svetlov和is.infinity应该是对的,因为我在测试期间忘记关闭create_pool方法中的连接池。@AndrewSvetlov你是对的。我按照is.infinity的建议关闭测试文件中的连接池,它就可以工作了。为什么在我将该方法运行_直到_完成(测试_更新(循环))在另一个异步方法中使用“yield from”,测试代码运行良好吗?它是否在运行时关闭连接池?谢谢你的帮助。