Python异步AttributeError aexit

时间:2018-02-05 15:29:49

标签: python-3.x async-await python-asyncio

我在下面的代码中不断收到错误AttributeError: __aexit__,但我真的不明白为什么会这样。

我的Python版本是:3.6.4 (v3.6.4:d48eceb, Dec 19 2017, 06:04:45) [MSC v.1900 32 bit (Intel)]

import aiohttp
import asyncio
import tqdm


async def fetch_url(session_, url_, timeout_=10):
    with aiohttp.Timeout(timeout_):
        async with session_.get(url_) as response:
            text = await response.text()
            print("URL: {} - TEXT: {}".format(url_, len(text)))
            return text


async def parse_url(session, url, timeout=10):
    # get doc from url
    async with await fetch_url(session, url, timeout) as doc:
        print("DOC: {}".format(doc, len(doc)))
        return doc


async def parse_urls(session, urls, loop):
    tasks = [parse_url(session, url) for url in urls]
    responses = [await f for f in tqdm.tqdm(asyncio.as_completed(tasks), total = len(tasks))]
    return responses


if __name__ == '__main__':

    tickers = ['CTXS', 'MSFT', 'AAPL', 'GPRO', 'G', 'INTC', 'SYNC', 'SYNA']
    urls = ["https://finance.yahoo.com/quote/{}".format(ticker) for ticker in tickers]

    loop = asyncio.get_event_loop()
    with aiohttp.ClientSession(loop=loop) as session:
        parsed_data = loop.run_until_complete(parse_urls(session, urls, loop))
        print(parsed_data)

错误callstack:

C:\Python\Python36\python.exe C:/Users/me/.PyCharmCE2017.3/config/scratches/scratch_4.py
  0%|          | 0/8 [00:00<?, ?it/s]Traceback (most recent call last):
URL: https://finance.yahoo.com/quote/CTXS - TEXT: 462138
  File "C:/Users/me/.PyCharmCE2017.3/config/scratches/scratch_4.py", line 34, in <module>
    parsed_data = loop.run_until_complete(parse_urls(session, urls, loop))
  File "C:\Python\Python36\lib\asyncio\base_events.py", line 467, in run_until_complete
    return future.result()
  File "C:/Users/me/.PyCharmCE2017.3/config/scratches/scratch_4.py", line 23, in parse_urls
    responses = [await f for f in tqdm.tqdm(asyncio.as_completed(tasks), total = len(tasks))]
  File "C:/Users/me/.PyCharmCE2017.3/config/scratches/scratch_4.py", line 23, in <listcomp>
    responses = [await f for f in tqdm.tqdm(asyncio.as_completed(tasks), total = len(tasks))]
  File "C:\Python\Python36\lib\asyncio\tasks.py", line 458, in _wait_for_one
    return f.result()  # May raise f.exception().
  File "C:/Users/me/.PyCharmCE2017.3/config/scratches/scratch_4.py", line 16, in parse_url
    async with await fetch_url(session, url, timeout) as doc:
AttributeError: __aexit__


Process finished with exit code 1

1 个答案:

答案 0 :(得分:3)

您正在尝试使用fetch_url作为上下文管理器,但它不是一个。你可以把它做成一个

class fetch_url:
    def __init__(self, session, url, timeout=10):
        self.session = session
        self.url = url
        self.timeout = timeout

    async def __aenter__(self):
        with aiohttp.Timeout(self.timeout):
            async with self.session.get(self.url) as response:
                text = await response.text()
                print("URL: {} - TEXT: {}".format(self.url, len(text)))
                return text

    async def __aexit__(self, exc_type, exc, tb):
        # clean up anything you need to clean up

或将您的代码更改为

async def parse_url(session, url, timeout=10):
    # get doc from url
    doc = await fetch_url(session, url, timeout)
    print("DOC: {}".format(doc, len(doc)))
    return doc