进口东西的对象范围如何工作?

时间:2013-04-29 09:50:48

标签: python scope twisted python-import

- 在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

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

2 个答案:

答案 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编辑多少次;它只会加载一次,其内部状态将在所有引用中共享。

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