我试图了解如何在Python 3.4中使用新的AsyncIO功能,我正在努力使用event_loop.add_reader().从我发现的有限讨论看起来它看起来像是从单独的进程中读取标准而不是打开文件的内容.真的吗?如果是这样,似乎没有AsyncIO特定的方式来集成标准文件IO,这也是真的吗?
我一直在玩以下代码.以下输出给出了PermissionError: [Errno 1] Operation not permitted/python3.4/selectors.py第399行的异常self._epoll.register(key.fd, epoll_events),它由add_reader()下面的行触发
import asyncio
import urllib.parse
import sys
import pdb
import os
def fileCallback(*args):
pdb.set_trace()
path = sys.argv[1]
loop = asyncio.get_event_loop()
#fd = os.open(path, os.O_RDONLY)
fd = open(path, 'r')
#data = fd.read()
#print(data)
#fd.close()
pdb.set_trace()
task = loop.add_reader(fd, fileCallback, fd)
loop.run_until_complete(task)
loop.close()
Run Code Online (Sandbox Code Playgroud)
编辑
对于那些寻找如何使用AsyncIO一次读取多个文件的例子,我很好奇,这里有一个如何实现它的例子.秘密就在于此yield from asyncio.sleep(0).这实际上暂停了当前函数,将其放回事件循环队列中,在执行所有其他就绪函数后调用.确定功能是根据它们的安排方式准备好的.
import asyncio
@asyncio.coroutine
def read_section(file, length):
yield from asyncio.sleep(0)
return file.read(length)
@asyncio.coroutine
def read_file(path):
fd …Run Code Online (Sandbox Code Playgroud) 我找不到aiohttp与登录页面结合的工作代码.目标很简单:使用用户名和密码进行基于表单的身份验证,我希望在随后的aiohttp async fetch调用中使用该cookie.
似乎整个Session概念在版本之间的aiohttp中发生了变化,所以我很好奇如何在最新版本中实现它.我不确定如何获取cookie一次,然后在异步事件中使用它.
我真的很想看到一个完整的例子,因为不幸的是我无法使用我在任何地方找到的片段.
我想这可能是一个开始,但我不确定,我当然不知道如何将所有内容连接到它(我还需要一个aiohttp.TCPConnector吗?)
http://aiohttp.readthedocs.org/en/latest/ client_reference.html#aiohttp.client.ClientSession
使用mechanize在Python 2中我的非异步版本的示例(虽然我自然地使用Python 3进行asyncio等):
import mechanize
import urllib
class MyClass()
def __init__(self):
self.data = {'username' : 'me', 'password' : 'pw'}
self.login_url = 'http://example.com/login'
self.login()
def call(self, url):
request2 = mechanize.Request(url)
self.cookie_jar.add_cookie_header(request2)
response2 = mechanize.urlopen(request2).read()
return response2
def login(self):
request = mechanize.Request(self.login_url)
# 'username' and 'password' keys are actually the name of the <input>
logInfo = urllib.urlencode({'username' : self.data['username'],
'password' : self.data['password']})
response = mechanize.urlopen(request, data = logInfo) …Run Code Online (Sandbox Code Playgroud) 如何混合
async with api.open() as o:
...
Run Code Online (Sandbox Code Playgroud)
和
o = await api.open()
Run Code Online (Sandbox Code Playgroud)
在一个功能?
由于第一需要的对象与__aenter__和__aexit__,但第二要求__await__,这应该是没有发电机await.
我的尝试是:
def AsyncContext(aenter, aexit):
class AsyncContextClass:
async def __aenter__(self):
return await aenter()
async def __aexit__(self, *args):
return await aexit(*args)
def __await__(self):
return (yield from aenter())
return AsyncContextClass()
Run Code Online (Sandbox Code Playgroud)
但是__await__如果aenter使用async def(TypeError: cannot 'yield from' a coroutine object in a non-coroutine generator)定义则失败.
它与@asyncio.coroutine装饰器工作正常aenter,但这是"脏".
我试图绕过Tornado和异步连接到Postgresql.我找到了一个可以在http://peewee-async.readthedocs.io/en/latest/上执行此操作的库.
我设计了一个小测试来比较传统的Peewee和Peewee-async,但不知何故异步工作得更慢.
这是我的应用:
import peewee
import tornado.web
import logging
import asyncio
import peewee_async
import tornado.gen
import tornado.httpclient
from tornado.platform.asyncio import AsyncIOMainLoop
AsyncIOMainLoop().install()
app = tornado.web.Application(debug=True)
app.listen(port=8888)
# ===========
# Defining Async model
async_db = peewee_async.PooledPostgresqlDatabase(
'reminderbot',
user='reminderbot',
password='reminderbot',
host='localhost'
)
app.objects = peewee_async.Manager(async_db)
class AsyncHuman(peewee.Model):
first_name = peewee.CharField()
messenger_id = peewee.CharField()
class Meta:
database = async_db
db_table = 'chats_human'
# ==========
# Defining Sync model
sync_db = peewee.PostgresqlDatabase(
'reminderbot',
user='reminderbot',
password='reminderbot',
host='localhost'
)
class SyncHuman(peewee.Model):
first_name = peewee.CharField() …Run Code Online (Sandbox Code Playgroud) 我知道如何使用pyopenssl获取证书信息,例如到期日期,但是可以使用aiohttp 响应对象吗?
我有一个生产代码,大量使用asyncio.semaphore模块,怀疑有死锁问题.我已经找到了一些解决方案,如何使用unix信号附加到运行python代码,调试ipdb.set_trace()并列出事件循环中的所有任务asyncio.Task.all_tasks().我可以进一步检查每个任务的堆栈框架,还是查看当前正在等待的各个协程路线ipdb?
我最近从请求交换到aiohttp,因为我无法在asyncio循环中使用它.
交换完美,一切顺利,除了一件事.我的控制台充满了
Attempt to decode JSON with unexpected mimetype:
Run Code Online (Sandbox Code Playgroud)
和
Attempt to decode JSON with unexpected mimetype: txt/html; charset=utf-8
Run Code Online (Sandbox Code Playgroud)
我的代码也有一个网站列表,它也可以抓取JSON,每个网站都不同,但我的循环基本上是相同的,我在这里简化了它:
PoolName = "http://website.com"
endpoint = "/api/stats"
headers = "headers = {'content-type': 'text/html'}" #Ive tried "application/json" and no headers
async with aiohttp.get(url=PoolName+endpoint, headers=headers) as hashrate:
hashrate = await hashrate.json()
endVariable = hashrate['GLRC']['HASH']
Run Code Online (Sandbox Code Playgroud)
它工作得很好,连接到站点抓取json并正确设置endVariable.但出于某种原因
Attempt to decode JSON with unexpected mimetype:
Run Code Online (Sandbox Code Playgroud)
每次进入循环时打印.这很烦人,因为它会向控制台打印统计信息,并且每次抓取站点json时它们都会在错误中丢失
有没有办法解决这个错误或隐藏它?
我想PyAudio在异步上下文中使用该库,但该库的主入口点只有一个基于回调的API:
import pyaudio
def callback(in_data, frame_count, time_info, status):
# Do something with data
pa = pyaudio.PyAudio()
self.stream = self.pa.open(
stream_callback=callback
)
Run Code Online (Sandbox Code Playgroud)
我希望如何使用它是这样的:
pa = SOME_ASYNC_COROUTINE()
async def listen():
async for block in pa:
# Do something with block
Run Code Online (Sandbox Code Playgroud)
问题是,我不确定如何将此回调语法转换为在回调触发时完成的未来.在JavaScript中我会使用promise.promisify(),但Python似乎没有这样的东西.
我有一个服务器应用程序,当客户要求我安排一些工作,如
def work():
time.sleep(5)
fut = asyncio.get_event_loop().run_in_executor(None, work)
Run Code Online (Sandbox Code Playgroud)
我await fut后来明确要求它.我的用例要求立即run_in_executor提交work函数,并且在我的环境中表现如预期(Ubuntu 16.04,Python 3.7.1).
由于我的应用程序依赖于这种行为,我想验证它不是可能改变的东西,所以我检查了几个资源:
asyncio.Future明确的.run_in_executor是一个协程.run_in_executor返回等待或协程本身的函数似乎被视为实现细节.见25675和32327.AbstractEventLoop.run_in_executor被指定为协程,但是实现BaseEventLoop.run_in_executor是一个普通的函数.1和2似乎主要表明当前的行为是正确的,但3和4是有关的.这似乎是界面的一个非常重要的部分,因为如果函数本身是一个协程,那么它将不会开始执行(因此不会安排工作),直到等待它为止.
依赖当前的行为是否安全?如果是这样,将接口更改AbstractEventLoop.run_in_executor为普通函数而不是协程是否合理?
我想使用asyncio获取网页html。
我在jupyter笔记本中运行以下代码:
import aiofiles
import aiohttp
from aiohttp import ClientSession
async def get_info(url, session):
resp = await session.request(method="GET", url=url)
resp.raise_for_status()
html = await resp.text(encoding='GB18030')
with open('test_asyncio.html', 'w', encoding='utf-8-sig') as f:
f.write(html)
return html
async def main(urls):
async with ClientSession() as session:
tasks = [get_info(url, session) for url in urls]
return await asyncio.gather(*tasks)
if __name__ == "__main__":
url = ['http://huanyuntianxiazh.fang.com/house/1010123799/housedetail.htm', 'http://zhaoshangyonghefu010.fang.com/house/1010126863/housedetail.htm']
result = asyncio.run(main(url))
Run Code Online (Sandbox Code Playgroud)
但是,它返回 RuntimeError: asyncio.run() cannot be called from a running event loop
问题是什么?
怎么解决呢?
非常感谢你。
python-asyncio ×10
python ×7
python-3.x ×4
aiohttp ×3
asynchronous ×1
debugging ×1
file-io ×1
ipdb ×1
json ×1
peewee ×1
postgresql ×1
pyaudio ×1
python-3.4 ×1
python-3.5 ×1
semaphore ×1
tornado ×1