为什么我的Python导入不起作用?
这个是可以正常工作的:
from story.apps.document import core
print core.submit()
这个就不行:
from story import apps
print apps.document.core.submit()
“story”是一个文件夹。在这个文件夹里,有一个叫“apps”的文件夹。在“apps”文件夹里,还有一个叫“document”的文件夹。而“core.py”是一个文件。
每个文件夹里都有一个叫__init__.py
的文件。
5 个回答
这只有在 story/__init__.py
文件里导入了 apps
的时候才有效。
当你写 story.apps.document import core
时,你是在告诉Python解释器去找一个叫 story.apps.document
的模块,把它导入进来,然后把这个模块里的 core
变量加载到你现在的环境中。
因为 core
是一个文件模块,它的命名空间里有这个文件中定义的变量,比如 submit
。
当你写 from story import apps
时,你是在告诉Python解释器去找一个叫 story
的模块,把它导入进来,然后把这个模块里的 apps
变量加载到你现在的环境中。
因为 apps
是一个目录模块,它的命名空间里有在它的 __init__.py
文件和这个目录下其他模块中定义的变量。所以 apps
知道 document
的存在,但它对 document
里的子模块 core
一无所知。
顺便说一下: 有时候人们会感到困惑的原因就是因为像这样的事情...
这个可以正常工作:
# File1
import story.apps.document
story.apps.document.core()
这个不行:
# File2
import story
story.apps.document.core() # <-- Looks like the same function call, but is an Error
对于 file1
,导入可以正常工作,因为 import
操作会智能地在文件系统中查找东西。函数调用可以工作是因为模块 document
已经被导入,它的名字就是 story.apps.document
。
对于 file2
,函数调用不工作是因为点操作符并没有智能,它只是试图访问Python对象的属性——它对文件系统或模块一无所知。
__init__.py
文件的作用是告诉 Python 把这个文件夹当作一个包来处理,但它并不一定会告诉 Python 自动导入这个文件夹里的子包或其他文件(不过如果你在里面加上合适的 import
语句,它是可以做到的)。
在有很多层级的包时,通常更好的是需要手动导入子包。