TypeError: A Future or coroutine is required
TypeError: A Future or coroutine is required
我尝试在 asyncssh 上制作自动重新连接的 ssh 客户端。 (SshConnectManager 必须留在后台并在需要时进行 ssh 会话)
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 return 需要调用什么函数来获取生成器对象。我忘记这样做了。
固定版本:
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(...)
P.S。但是我不明白为什么协程装饰器不能 return 调用装饰器。 (这让我很困惑,我把它和扭曲的回调搞混了)。
而且我找到了如何记住这个,有简单的情况,如果 start_connection 可以得到参数:
@asyncio.coroutine
def start_connection(self, some_arg):
pass
所以,我可以简单的写:
asyncio.async(self.start_connection(some_val))
不需要在asyncio.async函数中添加额外的属性
我尝试在 asyncssh 上制作自动重新连接的 ssh 客户端。 (SshConnectManager 必须留在后台并在需要时进行 ssh 会话)
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 return 需要调用什么函数来获取生成器对象。我忘记这样做了。
固定版本:
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(...)
P.S。但是我不明白为什么协程装饰器不能 return 调用装饰器。 (这让我很困惑,我把它和扭曲的回调搞混了)。
而且我找到了如何记住这个,有简单的情况,如果 start_connection 可以得到参数:
@asyncio.coroutine
def start_connection(self, some_arg):
pass
所以,我可以简单的写:
asyncio.async(self.start_connection(some_val))
不需要在asyncio.async函数中添加额外的属性