我有以下模块:
#include <iostream>
#include <vector>
using namespace std;
int main(){
int a;
int b;
int c;
int d;
int result;
while(cin >> a >> b >> c){
result = 0;
}
vector <int > v;
while(cin >> d);{
v.push_back(d);
}
for( int i = 0; i < v.size();i++);
cout << v[i] << endl;
if (a>=b) cout << 0 << endl;
else {
}
}
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'
中的import语句已将对内置模块的引用替换为对print_random()
的引用。谁能向我解释为什么它没有在上述表中添加新记录?我在哪里可以了解更多信息?有避免这种情况的推荐做法吗?
更新#1
我在Python 2.7和Python 3.5中都遇到了相同的错误。我注意到的唯一区别是,与Python 2相比,措词略有不同:foo.random
。
AttributeError: 'module' object has no attribute 'random'
中的 sys.modules['random']
指的是内置随机模块,而print_random()
指的是globals()['random']
。
foo/random.py
不必位于import foo.random
中。可以从那里删除它,并将其添加到运行脚本的命令中(例如python -c'import foo; import foo.random; foo.print_random()'),这将产生相同的结果。
答案 0 :(得分:2)
这里有两种机制:
一方面,当执行import foo.random
语句时,我们通常希望名称foo
将绑定在本地上下文中,并且foo.random
将作为成员可用导入语句的docs.
foo
另一方面,根据子模块doc,“使用任何一种机制加载子模块时,都会在父模块的命名空间中放置与子模块对象的绑定”。
在__init__.py
文件的特殊情况下,这意味着foo.random
可以作为名称random
和绑定到{的对象的random
成员使用{1}},因为在foo
文件中,我们直接在父模块的上下文中工作(即,我们在__init__.py
上下文中工作,而不是在foo
上下文中工作)。>
最好的解决方案是,如果可以避免的话,不要在foo.__init__
包中编写代码,而只是使用它公开名称,初始化记录器等。始终为以下模块创建包是一种很好的做法:尽管不能解决此问题,但相对于父包而言,它具有更好的表达能力。
最后,如果您想在具有以上内容的__init__
函数的同时公开foo.random
包,我建议采用以下布局:
foo.print_random
foo / __ init __。py
foo/
__init__.py
print_random.py
random/
__init__.py
foo / print_random.py
from foo.print_random import print_random