python导入的奇怪行为

时间:2009-11-11 09:40:05

标签: python import module

所以我试图导入一个包含目录“bar”和“wiz”的模块“foo”。 “bar”包含python文件a.py,b.py和c.py. “wiz”包含python文件x.py,y.py和z.py。

$ ls foo
__init__.py     bar       wiz
$ ls foo/bar
__init__.py     a.py      b.py      c.py
$ ls foo/wiz
__init__.py     x.py      y.py      z.py

在python shell(更准确地说是django manage.py shell)中,我键入以下内容并查看以下结果:

>>> import foo
>>> dir(foo.bar)
['__builtins__', '__doc__', '__file__', '__name__', '__path__', 'a']
>>> dir(foo.wiz)
['__builtins__', '__doc__', '__file__', '__name__', '__path__', 'x', 'y']
>>> foo.wiz.x
<module 'foo.wiz.x' from '/dir/'>
>>> foo.wiz.z
Traceback (most recent call last):
  File "<console>", line 1, in <module>
AttributeError: 'module' object has no attribute 'z'

为什么这里只导入某些模块?为什么我无法访问z,或者访问b或c?我认为所有内容都只能根据包含它们的目录导入和访问。此外,如果导入失败,则会无声地失败。

有谁知道这里发生了什么?

2 个答案:

答案 0 :(得分:2)

导入foo时,Python只会加载foo/__init__.py,而不会(自动)加载foo.barfoo.wiz。因此,尝试访问那些没有明确导入它们的人将会引发AttributeError

如果某个模块导入了foo.barfoo.bar.a等子模块,Python将加载相应的文件并在module中创建对foo对象的引用。因此,有些模块可以在没有明确导入的情况下使用。

如果您希望foo.bar始终导出其子模块abc,您可以从foo/bar/__init__.py内导入这些子模块。然后,只要导入foo.bar,这些模块就可用。

答案 1 :(得分:1)

您尚未导入“z”(x可能是在其他模块中导入的):

Python 2.4.3 (#1, Jan 14 2008, 18:31:21)
[GCC 4.1.2 20070626 (Red Hat 4.1.2-14)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import foo
>>> foo.wiz
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
AttributeError: 'module' object has no attribute 'wiz'
>>> from foo import wiz
>>> foo.wiz
<module 'foo.wiz' from 'foo/wiz/__init__.pyc'>
>>> from foo.wiz import x
>>> foo.wiz.x
<module 'foo.wiz.x' from 'foo/wiz/x.pyc'>
>>> foo.wiz.z
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
AttributeError: 'module' object has no attribute 'z'
>>> import foo.wiz.z
>>> foo.wiz.z
<module 'foo.wiz.z' from 'foo/wiz/z.py'>