- 在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
以及主要功能。
停在
def poetry_main():
...
def got_poem(poem):
poems.append(poem)
if len(poems) == len(addresses):
reactor.stop()
两个反应堆都指向同一个反应堆吗? 如何同样的多个导入工作?
另外为什么不定义
from twisted.internet import reactor
在程序的顶部,而不是在使用它之前的函数内部?
答案 0 :(得分:2)
有时在模块级别导入twisted.internet.reactor
的原因是导入的第一个时间,如果尚未明确选择特定的反应器实现,则默认选择将做成。选择实施后,就无法更改。
如果模块在顶层导入twisted.internet.reactor
,则只要导入它们,就会导入反应堆。这使得选择不同的反应器实现变得更加困难,因为在导入任何在顶层导入twisted.internet.reactor
的模块之前必须这样做。
因此,一个约定是仅在需要使用它的函数内导入twisted.internet.reactor
。这意味着在调用函数之前不会进行导入,这通常已经足够晚以至于已经选择了实现。
另一个约定(包括我自己在内的某些人更喜欢)是定义接受reactor作为参数的API。这样你根本不会导入反应堆,它会与你的功能所需的任何其他输入一起传递给你。
这种方法的一大优点是它使代码更易于单元测试。
答案 1 :(得分:0)
仔细观察,from twisted.internet import reactor
函数中还有另一个poetry_main
。与变量和函数一样,导入的范围是词汇。
关于这样做的原因,我可以想到不会污染模块的全局命名空间。
Python保留了导入模块的内部字典,因此无论模块import
编辑多少次;它只会加载一次,其内部状态将在所有引用中共享。
这对于允许循环模块依赖很重要,否则它将以无限递归结束。