62083


async await をつかった並列処理の勉強中なのですが

[code]

    import time
    
    async def sleep_echo(x):
      print('start' + x)
      time.sleep(10)
      print('end ' + x)
      return x
    
    result1 = await sleep_echo('1')
    result2 = await sleep_echo('2')
    print(result1)
    print(result2)
    
[/code]

これで

[code]

    SyntaxError: 'await' outside function
    
[/code]

がでるんですがなぜでしょうか

ロジックミスならともかく  
いろいろな記事を見ても await をメソッド前につけるだけなのに  
文法エラーになる理由がよくわかりません

outside function っていうから

[code]

    def main():
      result1 = await sleep_echo('1')
      result2 = await sleep_echo('2')
      print(result1)
      print(result2)
    
    main()
    
[/code]

と書いても同じです

async await を取り除けば動くことは確認しました  
await がかける位置に何か条件があるんでしょうか？


CC BY-SA 4.0
2020-01-09T00:01:32.413
62081
2020-01-13T22:43:10.137
2020-01-13T22:43:10.137
question
python
python の async await の使い方：'await' outside function


`await` は `async` で宣言された関数の中でのみ使えます。

<https://www.python.org/dev/peps/pep-0492/#await-expression>

> It is a SyntaxError to use await outside of an async def function (like it
> is a SyntaxError to use yield outside of def function).

並列処理という事なので、多分↓のようなコードになるのかな。

[code]

    import asyncio
    
    
    async def sleep_echo(x):
        print('start' + x)
        await asyncio.sleep(10)
        print('end ' + x)
        return x
    
    
    loop = asyncio.get_event_loop()
    
    tasks = asyncio.gather(
        sleep_echo('1'),
        sleep_echo('2'),
    )
    
    results = loop.run_until_complete(tasks)
    print(results)
    
[/code]

* * *

## 追記: asyncを使ったhttpリクエストの並列化

`aiohttp` を使うのが手っ取り早いと思います。

[code]

    import aiohttp
    import asyncio
    
    
    async def fetch(session, url):
        async with session.get(url) as response:
            print(await response.text())
    
    
    async def main():
        async with aiohttp.ClientSession() as session:
            await asyncio.gather(
                fetch(session, 'https://www.rakuten.co.jp/'),
                fetch(session, 'https://www.amazon.co.jp/'),
            )
    
    asyncio.run(main())
    
[/code]

* * *

### 追記: fork-exec-waitによるマルチプロセス(unix限定)

[code]

    import os
    import sys
    import time
    
    def count(n):
        for i in range(n):
            print(i)
            time.sleep(0.1)
    
    pid = os.fork()
    if pid == 0:
        count(10)
        os._exit(0)
    else:
        count(10)
    
    child_pid, status = os.waitpid(pid, 0)
    
    print("child_pid = %d, status= %d" % (child_pid, status))
    
[/code]

もちろんこれは `multiprocessing` モジュールで以下のように書けます。

[code]

    import multiprocessing as mp
    import time
    
    def count(n):
        for i in range(n):
            print(i)
            time.sleep(0.1)
    
    for num in range(2):
        mp.Process(target=count, args=(10,)).start()
    
[/code]


CC BY-SA 4.0
2020-01-09T01:31:51.680
62083
2020-01-12T23:35:44.690
2020-01-12T23:35:44.690
62
62
62081
answer