Python 导入语句如何修改模块';s符号表?

Python 导入语句如何修改模块';s符号表?,python,Python,我有以下模块: foo/ __init__.py random.py random.py只是一个空文件,并且\uuuuu init\uuuuuu.py包含以下内容: 随机导入 def print_random(): 导入foo.random 打印(random.random()) 当我用python-c'import-foo调用上述函数时;foo.print_random()',我得到的是属性错误:模块'foo.random'没有属性'random' print\u random

我有以下模块:

foo/
   __init__.py
   random.py
random.py
只是一个空文件,并且
\uuuuu init\uuuuuu.py
包含以下内容:

随机导入
def print_random():
导入foo.random
打印(random.random())
当我用
python-c'import-foo调用上述函数时;foo.print_random()'
,我得到的是
属性错误:模块'foo.random'没有属性'random'

print\u random()
中的导入语句似乎已将对内置模块的引用替换为对
foo.random
的引用。有谁能向我解释一下,为什么它没有在上述表格中添加新记录?我在哪里可以读到更多关于它的信息?是否有避免这种情况的推荐做法

更新#1

我在Python2.7和Python3.5中都遇到了相同的错误。我注意到的唯一区别是Python 2的措辞略有不同:
AttributeError:'module'对象没有属性“random”

print\u random()
中的
sys.modules['random']
指的是内置的随机模块,而
globals()['random']
指的是
foo/random.py


import foo.random
不必位于
print\u random()
中。它可以从那里删除并添加到用于运行脚本的命令中(例如python-c'import foo;import foo.random;foo.print_random()),这将产生相同的结果。

这里有两种机制:

一方面,当执行
import foo.random
语句时,我们通常希望名称
foo
将绑定在本地上下文中,并且
foo.random
将作为
foo
的成员,根据import语句的

另一方面,“当使用任何机制加载子模块时,[…]会在父模块的命名空间中放置到子模块对象的绑定”每个子模块

\uuuu init\uuuuuuuuuupy
文件的特殊情况下,这意味着
foo.random
将作为绑定到
foo
的对象的
random
成员,因为在
\uuuuuuuuuuuuupy
文件中,我们直接在父模块的上下文中工作(即,我们是在
foo
上下文中工作,而不是在
foo.\uuuu init\uuuu
上下文中工作)

最好的解决方案是,如果可以避免的话,不要在
\uuuu init\uuuuu
包中编写代码,只需使用它来公开名称、初始化记录器等。同时,始终为要相对于父包公开的模块创建一个包以提高表达能力也是一个很好的做法,尽管这并不能解决此问题

总之,如果您想公开一个
foo.random
包,同时拥有一个带有上述内容的
foo.print\u random
函数,我建议如下布局:

foo/
  __init__.py
  print_random.py
  random/
    __init__.py
foo/\uuuuuu init\uuuuuuuuuuuuuuuuuuuuuuuuy.py

from foo.print_random import print_random
foo/print_random.py

import random

def print_random():
    import foo.random
    print(random.random())

这可能不相关,但您使用的是哪一版本的Python?不,
import random
正在导入它找到的第一个
random.py
import foo.random
不会以任何方式影响代码的行为。根据您链接到的文档,“此映射[sys.modules]用作以前导入的所有模块(包括中间路径)的缓存”(强调添加)。为什么希望它包含内置的随机路径?至于建议的做法:如果没有明确的隐藏意图,请不要将一个模块命名为另一个模块。(找不到这样的链接,但这似乎是常识)。这是一个与
\uuuuu init\uuuu
文件相关的特例,现在编写更长的答案。添加了更详细的文件布局示例