python - 类型错误 : A Future or coroutine is required

标签 python python-asyncio

我尝试在 asyncssh 上创建自动重新连接的 ssh 客户端。 (SshConnectManager 必须留在后台并在需要时进行 ssh session )

class SshConnectManager(object):
def __init__(self, host, username, password, port=22):
    self._host = host
    self._username = username
    self._password = password
    self._port = port

    self.conn = None
    asyncio.async(self.start_connection)

@asyncio.coroutine
def start_connection(self):
    try:
        Client = self._create_ssh_client()
        self.conn, _ = yield from asyncssh.create_connection(Client,
                                                        self._host, port=self._port,
                                                        username=self._username,
                                                        password=self._password)
    except Exception as e:
        print("Connection error! {}".format(e))
        asyncio.async(self.start_connection())

def _create_ssh_client(self):
    class MySSHClient(asyncssh.SSHClient):
        parent = self
        def connection_lost(self, exc):
            self.parent._handle_connection_lost(exc)
    return MySSHClient

def _handle_connection_lost(self, exc):
    print('Connection lost on {}'.format(self.host))
    print(exc)
    asyncio.async(self.start_connection)


ssh1 = SshConnectManager(settings.host, settings.username, settings.password, settings.port)

asyncio.get_event_loop().run_until_complete(...)

请不要查看 _create_ssh_client 或其他“haks”

问题是:

$ python3 main.py 
Traceback (most recent call last):
  File "main.py", line 75, in <module>
    ssh1 = SshConnectManager(settings.host, settings.username, settings.password, settings.port)
  File "main.py", line 22, in __init__
    asyncio.async(self.start_connection)
  File "/usr/lib/python3.4/asyncio/tasks.py", line 565, in async
    raise TypeError('A Future or coroutine is required')
TypeError: A Future or coroutine is required

但是 self.start_connection 是协程的!或不? 或者从同步代码启动异步任务的另一种方法是什么?

最佳答案

感谢@dano 和@boardrider 在评论中提供的帮助。 错误是 @asyncio.coroutine 返回函数需要调用什么来获取生成器对象。我忘了这样做。

固定版本:

class SshConnectManager(object):
def __init__(self, host, username, password, port=22):
    self._host = host
    self._username = username
    self._password = password
    self._port = port

    self.conn = None
    # FIX HERE
    asyncio.async(self.start_connection())

@asyncio.coroutine
def start_connection(self):
    try:
        Client = self._create_ssh_client()
        self.conn, _ = yield from asyncssh.create_connection(Client,
                                                        self._host, port=self._port,
                                                        username=self._username,
                                                        password=self._password)
    except Exception as e:
        print("Connection error! {}".format(e))
        asyncio.async(self.start_connection())

def _create_ssh_client(self):
    class MySSHClient(asyncssh.SSHClient):
        parent = self
        def connection_lost(self, exc):
            self.parent._handle_connection_lost(exc)
    return MySSHClient

def _handle_connection_lost(self, exc):
    print('Connection lost on {}'.format(self.host))
    print(exc)
    # AND HERE
    asyncio.async(self.start_connection())


ssh1 = SshConnectManager(settings.host, settings.username, settings.password, settings.port)

asyncio.get_event_loop().run_until_complete(...)

附言但我不明白为什么协程装饰器不能返回调用的装饰器。 (这让我感到困惑,我将其与扭曲的回调混淆了)。

我找到了如何记住这个,有一个简单的例子,如果 start_connection 可以得到参数:

@asyncio.coroutine
def start_connection(self, some_arg):
    pass

所以,我可以简单的写:

asyncio.async(self.start_connection(some_val))

并且不需要在 asyncio.async 函数中添加额外的属性

关于python - 类型错误 : A Future or coroutine is required,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30450533/

相关文章:

python - Discord.py Cog//如何发送消息到特定 channel

Python setuptools 符号链接(symbolic link)和自定义安装扩展

python-3.x - Selenium 和异步

python - Python 3.4 中的 "async with"

python - 我应该在另一个进程/线程中调用我的异步函数吗?

Python 类堆栈框架限制

Python数字组合生成器需要递归

python - 如何正确安装包含在 .zip 文件(包括一堆不同的文件格式)中的 python 包(PyXLL)?

python-3.x - 剖析异步 websocket 应用程序

python - 区分取消屏蔽任务和当前任务