2

--在fortan的回答之后编辑----

从这里https://github.com/jdavisp3/twisted-intro/blob/master/twisted-client-3/get-poetry.py

反应堆是进口的

def get_poetry(host, port, callback):
  ...
  from twisted.internet import reactor

以及在 main 函数中。

并停在

def poetry_main():
  ...
  def got_poem(poem):
        poems.append(poem)
        if len(poems) == len(addresses):
            reactor.stop()

那么两个反应器都指向同一个反应器吗?同一事物的多个导入如何工作?

还有为什么不直接定义

from twisted.internet import reactor

在程序的顶部,而不是在使用它之前的函数内部?

4

2 回答 2

2

有时没有在模块级别导入的原因twisted.internet.reactor一次导入时,如果尚未明确选择特定的反应器实现,则会进行默认选择。一旦选择了实现,就无法更改。

如果模块twisted.internet.reactor在顶层导入,那么一旦它们被导入,反应器就会被导入。这使得选择不同的反应器实现变得有些困难,因为您必须在导入任何twisted.internet.reactor在顶层导入的模块之前这样做。

因此,一种约定是只导入twisted.internet.reactor需要使用它的内部函数。这意味着在调用函数之前不会发生导入,这通常已经足够晚了,以至于已经选择了实现。

另一个约定(包括我自己在内的一些人更喜欢)是定义接受反应器作为参数的 API。这样,您根本不会导入反应器,它会与您的函数需要的任何其他输入一起传递给您。

这种方法的一大优点是它使代码更容易进行单元测试。

于 2013-04-29T12:21:20.067 回答
0

如果你仔细观察,还有另一个功能from twisted.internet import reactorpoetry_main导入的范围是词法的,就像变量和函数一样。

关于这样做的原因,我可以想到不污染模块的全局命名空间。

Python 保留了导入模块的内部字典,因此无论模块被import编辑多少次;它只会被加载一次,并且它的内部状态将在所有引用之间共享。

这对于允许循环模块依赖很重要,否则将以无限递归结束。

于 2013-04-29T09:57:48.640 回答