在Stackoverflow上问了个关于import的问题 没什么人回答 转到这里 望解答

2012-02-17 17:25:24 +08:00
 janusle
就不翻译啦 很浅的英语

The following is structure of my program

./abc.py

./a/__init__.py

./b/__init__.py

./b/t.py

Source code of abc.py

=============
import a
=============

Source code of ./a/__init__.py

=======================
from b import t
=======================

Source of of ./b/t.py

=================
def aa():
print "bbb"
=================

./b/__init__.py is an empty file.

There is a statement

========
t.aa()
========

if I put it into ./a/__init__.py, then when I run abc.py, it works fine. But if I put it into abc.py, when I run the script, I get an error like

Traceback (most recent call last): File "abc.py", line 3, in t.aa() NameError: name 't' is not defined

What's the reason of this? Thank you in advance.
4370 次点击
所在节点    Python
10 条回复
binux
2012-02-17 17:43:02 +08:00
a.t.aa() ?
lyxint
2012-02-17 17:53:34 +08:00
如果放在abc.py里, 那么abc.py是这样子:

import a
t.bb()

肯定报NameError
janusle
2012-02-17 18:55:28 +08:00
@lyxint 我其实不明白 a和b是同级的目录 为什么a里面可以import到b的内容?
janusle
2012-02-17 19:01:43 +08:00
@lyxint 还有 就是我的理解是这样的 如果把t.aa()放在a目录的__init__.py里面

abc.py 一旦import a

它就变成
from b import t

t.aa()

这和我直接把t.aa()放在abc.py里面应该一样啊?
难道python的import方式不是这样吗?

我是以c和php的经验来猜测的
janusle
2012-02-17 19:04:16 +08:00
@binux 有点看懂了 我其实还是不理解 为什么 a能import到b的内容 我理解的是 python搜索应该是 向下搜索啊 这个时候 a的__init__.py在a下面 怎么能够找到上层目录(a)的同级目录b里面的内容呢?
binux
2012-02-17 19:19:21 +08:00
@janusle 不是,当你在abc这一级执行的时候,搜索目录是包含./的,在这一层当然是能找到b的

你可以这么测试,在a的目录中执行python __init__.py,这时候就找不到b了

然后
你在a/__init__.py中加上
print sys.path
执行abc.py的时候,就知道查找路径了
janusle
2012-02-17 19:35:18 +08:00
@binux 有点明白了 再问一个问题 如果在./a/__init__.py 里面的放入t.aa() 我在abc这一级执行的时候 python再前面加了包名 则变成a.t.aa() 是这样么?
binux
2012-02-17 19:42:58 +08:00
@janusle 不是这个原因

from b import t
这一句话已经将t导入当前的命名空间里了,那就可以直接t.aa()了

如果你在abc.py中这么写
from a import t
也是一样可以t.aa()的

import a
只是将module a导入到当前命名空间中,而不是a里面的东西。
janusle
2012-02-17 19:51:32 +08:00
@binux 恩恩 明白啦 谢谢 我再去看一点 命名空间的东西
clowwindy
2012-02-17 21:40:15 +08:00
推荐在所有文件里import都写绝对模块名,不要用相对的模块名,增加可读性。
http://www.python.org/dev/peps/pep-0008/

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/27584

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX