简体   繁体   English

python导入的奇怪行为

[英]Strange behavior with python import

So I am trying to import a module "foo" that contains directories "bar" and "wiz". 因此,我试图导入包含目录“ bar”和“ wiz”的模块“ foo”。 "bar" contains python files a.py, b.py, and c.py. “ bar”包含python文件a.py,b.py和c.py。 "wiz" contains python files x.py, y.py and z.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

In the python shell (more precisely, the django manage.py shell), I type the following and see the following results: 在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'

Why are only certain modules being imported here? 为什么只在这里导入某些模块? Why can't I get access to z, or to b or c for that matter? 为什么我不能访问z或b或c? I thought everything would be imported and accessible based solely on the directory that contained them. 我认为所有内容都将完全基于包含它们的目录导入和访问。 Also, if the import is failing, it is failing silently. 另外,如果导入失败,则将以静默方式失败。

Does anyone know what is going on here? 有人知道这是怎么回事吗?

When importing foo , Python will just load foo/__init__.py , it will not (automatically) load foo.bar or foo.wiz . 导入foo ,Python只会加载foo/__init__.py ,而不会(自动)加载foo.barfoo.wiz Therefore, trying to access those without explicitely importing them will raise a AttributeError . 因此,尝试在不显式导入它们的情况下访问它们将引发AttributeError

If some module imports sub-modules like foo.bar or foo.bar.a , Python will load the respective files and create a reference to the module object within foo . 如果某些模块导入了诸如foo.barfoo.bar.a类的子模块,Python将加载相应的文件并在foo创建对该module对象的引用。 So it is possible that some modules are available without explicit import. 因此,某些模块可能无需显式导入即可使用。

If you want foo.bar to always export its submodules a , b and c , you can import those from within foo/bar/__init__.py . 如果希望foo.bar始终导出其子模块abc ,则可以从foo/bar/__init__.py导入它们。 Then, these modules will be availabe whenever foo.bar is imported. 然后,每当导入foo.bar时,这些模块都将可用。

You haven't imported "z" (x was probably imported in some other module): 您尚未导入“ 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'>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM