Я пытаюсь понять поведение кода ниже. Я попытался зарегистрировать функцию обратного вызова trampoline
для вызова в цикле событий с помощью модуля asyncio
. Сам trampoline
вызывается несколько раз, и я уверен, почему это произошло, пожалуйста. Я ожидал, что обратный вызов trampoline
вызовет сам себя только один раз через 0.5
секунд?
import asyncio
import datetime
loop = asyncio.get_event_loop()
def print_date():
print(datetime.datetime.now())
def trampoline(name: str = "") -> None:
print("name:", end = " ")
print_date()
loop.call_later(0.5, trampoline, name)
loop.call_soon(trampoline())
loop.call_later(8, loop.stop)
loop.run_forever()
Вывод: у меня также есть исключение, в котором я тоже не уверен:
name: 2022-11-11 16:29:04.335313
Exception in callback None()
handle: <Handle>
Traceback (most recent call last):
File "C:\Anaconda3\lib\asyncio\events.py", line 81, in _run
self._context.run(self._callback, *self._args)
TypeError: 'NoneType' object is not callable
name: 2022-11-11 16:29:04.850481
name: 2022-11-11 16:29:05.363303
name: 2022-11-11 16:29:05.872649
name: 2022-11-11 16:29:06.383004
name: 2022-11-11 16:29:06.898766
name: 2022-11-11 16:29:07.413907
name: 2022-11-11 16:29:07.915795
name: 2022-11-11 16:29:08.428609
name: 2022-11-11 16:29:08.939604
name: 2022-11-11 16:29:09.454111
name: 2022-11-11 16:29:09.966438
name: 2022-11-11 16:29:10.470832
name: 2022-11-11 16:29:10.981675
name: 2022-11-11 16:29:11.496746
name: 2022-11-11 16:29:12.011841
Process finished with exit code 0
Полагаю, вы не хотите вызывать trampoline(), а вместо этого хотите передать функцию?
@tfeldmann, так ты говоришь, что это должно быть просто loop.call_soon(trampoline)
верно?
Проблема в том, что trampoline
планирует обратный вызов самому себе при вызове.
Это означает, что trampoline
будет вызываться через 0,5 секунды, снова переназначая обратный вызов самому себе на 0,5 секунды позже.
Чтобы он вызывался только один раз, вы должны удалить .call_later
изнутри trampoline
и переместить его наружу:
...
def trampoline(name: str = "") -> None:
print("name:", end = " ")
print_date()
loop.call_later(0.5, trampoline)
...
Исключение связано с вызовом .call_soon
с trampoline()
(возвращаемое значение: None
) вместо trampoline
(сама функция)
Спасибо. Почему он останавливается после некоторых звонков? В коде использовалось loop.run_forever()
, поэтому не должно ли trampoline()
работать вечно?
Я думаю, это потому, что мы вызываем loop.call_later(8, loop.stop)
, который останавливает цикл событий.
«Я ожидал, что батут обратного вызова вызовет сам себя только один раз через 0,5 секунды». Да, и что происходит, когда происходит второй вызов
trampoline
?