1.Почему reactor.run()
не вызывается в примерах .tac
файлов?
.tac
Файлы предназначены для загрузки с помощью инструмента командной строки "twistd
", который запускает реактор для вас.
Запуск реактора - это то, что делается один раз, независимо от того, какой бит кода служит основным пунктом вашей программы.Большая часть кода Twisted фактически представляет собой плагин некоторого вида, предназначенный для работы в контексте более крупной системы.
В конкретном случае файлов .tac
они никогда не должны запускаться как отдельныеодни только программы на Python: их задача - создать объект Application
(с прикрепленной связкой объектов Service
), который запускается при работе реактора.Важно, чтобы сам файл tac
не выполнял много работы сам по себе, потому что (например) рассматриваемые реализации Service
могут нуждаться в разделении кода, который должен запускаться как привилегированный и непривилегированный, что является сложным процессом;если работа выполняется в самом .tac
, она может быть выполнена случайно как неправильный пользователь.
2.Как я могу использовать Deferred
s внутри приложения Twisted без вызова reactor.run()
?
Deferred
- это просто механизм управления цепочками обратных вызовов.Вам не нужно звонить reactor.run()
, или даже вообще иметь реактор, чтобы использовать их.Например:
>>> from twisted.internet.defer import Deferred
>>> d = Deferred()
>>> def hello(result):
... print "'d' was fired:", result
... return result + 3
...
>>> d.addCallback(hello)
<Deferred at ...>
>>> print d
<Deferred at ...>
>>> d.callback(7)
'd' was fired: 7
>>> print d
<Deferred at ... current result: 10>
Тем не менее, многие API, которые возвращают Deferred
, нуждаются в реакторе, чтобы выполнить некоторую работу, чтобы в конечном итоге вызвать .callback()
на нем.Например, если вы сделаете ...
>>> from twisted.internet.task import deferLater
>>> from twisted.internet import reactor
>>> deferLater(reactor, 1.0, lambda: 20).addCallback(hello)
<Deferred at ...>
>>>
... вы будете сидеть без дела вечно, ожидая, пока это не произойдет, если кто-то не запустит реактор.Ничего не будет печататься, пока это не произойдет.
Но, если реактор уже работает - например, если вы запускали этот интерактивный пример в python -m twisted.conch.stdio
, а не python
, вы увидите, что Deferred
получитперезвонил через секунду, потому что это интерактивное приглашение уже запускает реактор.
3.В чем различия между витыми сценариями и приложениями?
Это не формально разделенные термины.Любой скрипт Python может потенциально импортировать код из Twisted и использовать его любым способом, поэтому трудно сказать, что какое-либо конкретное свойство применимо к «скриптам», за исключением того, что они являются компьютерными программами: -).
Если поTwisted Application, вы имеете в виду файл или плагин .tac
, разница в том, что этот вид кода разделяется на часть, которая создает сервис (код на верхнем уровне в вашем файле или плагине * 1045) и частьэто действительно делает работу (privilegedStartService
/ startService
/ stopService
реализации сервисов, которые устанавливает указанный код верхнего уровня).Кроме того, код, который выполняется в этом контексте (то есть управляется twistd
), не должен запускать сам реактор, поскольку он будет настроен и запущен самим twistd
.Поэтому такой код должен также быть осторожным, чтобы избежать импорта twisted.internet.reactor
, потому что twistd
предоставляет возможность использовать различных реакторов (select
, poll
, epoll
, kqueue
и т. Д.)и импорт реактора до того, как twistd
сможет его настроить, нарушит эту функцию.