2017-06-19 34 views
2

我有這樣的代碼:爲什麼我在Windows上獲取NotImplementedError異步並等待?

import os 
import time 
import asyncio 


async def run_command(*args): 
    """ 
    Example from: 
     http://asyncio.readthedocs.io/en/latest/subprocess.html 
    """ 
    # Create subprocess 
    process = await asyncio.create_subprocess_exec(
     *args, 
     # stdout must a pipe to be accessible as process.stdout 
     stdout=asyncio.subprocess.PIPE) 

    # Wait for the subprocess to finish 
    stdout, stderr = await process.communicate() 

    # Result 
    result = stdout.decode().strip() 

    # Return stdout 
    return result 


def run_asyncio_commands(tasks): 
    """Run tasks using asyncio and return results""" 
    loop = asyncio.get_event_loop() 
    commands = asyncio.gather(*tasks) # Unpack list using * 
    results = loop.run_until_complete(commands) 
    loop.close() 
    return results 


if __name__ == '__main__': 

    start = time.time() 

    cmds = [ 
     ['du', '-sh', '/Users/fredrik/Desktop'], 
     ['du', '-sh', '/Users/fredrik'], 
     ['du', '-sh', '/Users/fredrik/Pictures'] 
    ] 

    tasks = [] 
    for cmd in cmds: 
     tasks.append(run_command(*cmd)) 
    results = run_asyncio_commands(tasks) 
    print(results) 

    end = time.time() 
    print('Script ran in', str(end - start), 'seconds') 

當我在我的Mac上運行的Python 3.6.1的代碼,我得到這個:

['780K\t/Users/fredrik/Desktop', '46G\t/Users/fredrik', '52M\t/Users/fredrik/Pictures'] 
Script ran in 6.405519008636475 seconds 

但是當我在Windows上運行相同的腳本(但隨着du命令取代到一些東西,在Windows上運行),也與Python 3.6.1,我得到這個:

Traceback (most recent call last): 
    File "C:\Users\iruser\Desktop\asynciotest.py", line 66, in <module> 
    results = run_asyncio_commands(tasks) 
    File "C:\Users\iruser\Desktop\asynciotest.py", line 41, in run_asyncio_commands 
    results = loop.run_until_complete(commands) 
    File "C:\Users\fredrik\condaenvs\dev_py36\lib\asyncio\base_events.py", line 466, in run_until_complete 
    return future.result() 
    File "C:\Users\iruser\Desktop\asynciotest.py", line 16, in run_command 
    stdout=asyncio.subprocess.PIPE) 
    File "C:\Users\fredrik\condaenvs\dev_py36\lib\asyncio\subprocess.py", line 225, in create_subprocess_exec 
    stderr=stderr, **kwds) 
    File "C:\Users\fredrik\condaenvs\dev_py36\lib\asyncio\base_events.py", line 1190, in subprocess_exec 
    bufsize, **kwargs) 
    File "C:\Users\fredrik\condaenvs\dev_py36\lib\asyncio\coroutines.py", line 210, in coro 
    res = func(*args, **kw) 
    File "C:\Users\fredrik\condaenvs\dev_py36\lib\asyncio\base_events.py", line 340, in _make_subprocess_transp 
ort 
    raise NotImplementedError 
NotImplementedError 

這是我替代Unix命令在Windows上:

cmds = [['C:/Windows/system32/HOSTNAME.EXE']] 

Windows版本信息:不同的方式實現

Python 3.6.1 | packaged by conda-forge | (default, May 23 2017, 14:21:39) [MSC v.1900 64 bit (AMD64)] on win32 
Windows 10 Pro, version 1703, OS build 15063.413 

回答

5

不同的事件循環。其中一些有限制(有時與操作系統有關)。默認情況下,Windows使用SelectorEventLoop,正如你可以看到doc

SelectorEventLoop特定的限制:使用

  • SelectSelector只支持插座和限制爲512座。
  • add_reader()和add_writer()只接受套接字的文件描述符
  • 管道不支持(例如:connect_read_pipe(),connect_write_pipe())
  • 子過程中不支持(例如:subprocess_exec(),subprocess_shell( ))

要在Windows中運行你的代碼,你可以使用默認的可用的替代事件循環 - ProactorEventLoop

更換行:

loop = asyncio.get_event_loop() 

與此:

loop = asyncio.ProactorEventLoop() 
asyncio.set_event_loop(loop) 

您的代碼將工作。