我有以下模块:
foo/
__init__.py
random.py
random.py
只是一个空文件,__init__.py
包含以下内容:
import random
def print_random():
import foo.random
print(random.random())
当我用python -c 'import foo; foo.print_random()'
调用上述函数时,得到的是AttributeError: module 'foo.random' has no attribute 'random'
。你知道吗
似乎print_random()
中的import语句已将对内置模块的引用替换为对foo.random
的引用。有人能解释一下为什么它没有在前面提到的表中添加新记录吗?我在哪里能读到更多关于它的资料?有没有避免这种情况的推荐做法?你知道吗
更新#1
我在Python2.7和Python3.5中都遇到了相同的错误。我注意到的唯一区别是python2的措辞略有不同:AttributeError: 'module' object has no attribute 'random'
。你知道吗
print_random()
中的sys.modules['random']
指的是内置的随机模块,而globals()['random']
指的是foo/random.py
。你知道吗
import foo.random
不必在print_random()
中。它可以从那里删除并添加到用于运行脚本的命令中(例如python-c'import foo;import)foo.random公司; foo.print\u随机()'),这将产生相同的结果。你知道吗
这里有两种机制:
一方面,在执行
import foo.random
语句时,我们通常希望名称foo
将绑定在本地上下文中,并且foo.random
将作为foo
的成员根据import语句的docs.可用另一方面,根据子模块doc,“当使用任何机制[…]加载子模块时,会在父模块的命名空间中放置到子模块对象的绑定”。你知道吗
在
__init__.py
文件的特殊情况下,这意味着foo.random
既可以作为名称random
也可以作为绑定到foo
的对象的random
成员,因为在__init__.py
文件中,我们直接在父模块的上下文中工作(即,我们在foo
上下文中工作,而不是在foo.__init__
上下文中工作)。你知道吗最好的解决方案是,如果可以避免的话,不要在
__init__
包中编写代码,而只使用它来公开名称、初始化记录器等。通常为要相对于父包公开的模块创建一个包以获得表达能力也是一个很好的做法,尽管它不能解决这个问题。你知道吗总之,如果您想公开一个
foo.random
包,同时拥有一个foo.print_random
函数和上述内容,我建议您使用以下布局:foo/\uuu初始化\uuuuuuuuuy.py
foo/打印_随机.py你知道吗
相关问题 更多 >
编程相关推荐