使用 __init__.py 导入 Python 子模块
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24302754/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python submodule imports using __init__.py
提问by Benjamin
I'm learning Python, and I can't figure out how imports in __init__.py
work.
我正在学习 Python,但我无法弄清楚导入是如何__init__.py
工作的。
I understand from the Python tutorialthat the __init__.py
file initializes a package, and that I can import subpackages here.
我从Python 教程中了解到该__init__.py
文件会初始化一个包,并且我可以在此处导入子包。
I'm doing something wrong, though. Could you explain for me (and for future Python-learners) what I'm doing wrong?
不过,我做错了什么。您能否为我(以及未来的 Python 学习者)解释一下我做错了什么?
Here's a simplified example of what I'm trying to do.
这是我正在尝试做的一个简化示例。
This is my file structure:
这是我的文件结构:
package
__init__.py
test.py
subpackage
__init__.py
hello_world.py
The contents of hello_world.py
:
内容hello_world.py
:
def do_something():
print "Hello, world!"
subpackage/__init__.py
is empty.
subpackage/__init__.py
是空的。
package/__init__.py
contains:
package/__init__.py
包含:
import test.submodule.do_something
And finally, test.py
contains:
最后,test.py
包含:
do_something()
This is how I attempt to run hello_world.py using OSX terminal and Python 3:
这就是我尝试使用 OSX 终端和 Python 3 运行 hello_world.py 的方式:
python test.py
Python then throws the following error:
Python然后抛出以下错误:
NameError: name 'do_something' is not defined
采纳答案by holdenweb
You probably already understand that when you import a module, the interpreter creates a new namespace and executes the code of that module with the new namespace as both the local and global namespace. When the code completes execution, the module name (or the name given in any as
clause) is bound to the module object just created within the importing namespace and recorded against its __name__
in sys.modules
.
您可能已经了解,当您导入一个模块时,解释器会创建一个新的命名空间,并使用新的命名空间作为本地和全局命名空间来执行该模块的代码。当代码完成执行时,模块名称(或任何子as
句中给出的名称)绑定到刚刚在导入命名空间中创建的模块对象,并记录在其__name__
in 中sys.modules
。
When a qualified name such as package.subpackage.module
is imported the first name (package
) is imported into the local namespace, then subpackage
is imported into package
's namespace and finally module
is imported into package.subpackage
's namespace. Imports using from ... import ... as ...
perform the same sequence of operations, but the imported objects are bound directly to names in the importing module's namespace. The fact that the package name isn't bound in your local namespace does not mean it hasn't been imported (as inspection of sys.modules
will show).
当一个限定名称如package.subpackage.module
被导入时,名字(package
)被导入到本地命名空间,然后subpackage
被导入到package
的命名空间,最后module
被导入到package.subpackage
的命名空间。导入使用from ... import ... as ...
执行相同的操作序列,但导入的对象直接绑定到导入模块命名空间中的名称。包名称未绑定在您的本地命名空间中的事实并不意味着它没有被导入(如检查sys.modules
将显示)。
The __init__.py
in a package serves much the same function as a module's .py
file. A package, having structure, is written as a directory which can also contain modules (regular .py
files) and subdirectories (also containing an __init__.py
file) for any sub_packages. When the package is imported a new namespace is created and the package's __init__.py
is executed with that namespace as the local and global namespaces. So to answer your problem we can strip your filestore down by omitting the top-level package, which will never be considered by the interpreter when test.py
is run as a program. It would then look like this:
该__init__.py
包中的很多功能相同的模块的.py
文件。具有结构的包被写成一个目录,该目录还可以包含任何 sub_packages 的模块(常规.py
文件)和子目录(也包含一个__init__.py
文件)。当包被导入时,会创建一个新的命名空间,并__init__.py
使用该命名空间作为本地和全局命名空间来执行包。所以为了回答你的问题,我们可以通过省略顶级包来剥离你的文件存储,当test.py
作为程序运行时,解释器永远不会考虑它。然后它看起来像这样:
test.py
subpackage/
__init__.py
hello_world.py
Now, subpackage
is no longer a sub-package, as we have removed the containing package as irrelevant. Focusing on why the do_something
name is undefined might help. test.py
does not contain any import, and so it's unclear how you are expecting do_something
to acquire meaning. You could make it work by using an empty subpackage/__init__.py
and then test.py
could read
现在,subpackage
不再是子包,因为我们已经删除了包含不相关的包。关注do_something
名称未定义的原因可能会有所帮助。test.py
不包含任何导入,因此不清楚您希望do_something
如何获得意义。您可以通过使用空来使其工作subpackage/__init__.py
,然后test.py
可以读取
from subpackage.hello_world import do_something
do_something()
Alternatively you could us a subpackage/__init__.py
that reads
或者你可以给我们subpackage/__init__.py
读
from hello_world import do_something
which establishes the do_something
function inside the subpackage
namespace when the package is imported. Then use a test.py
that imports the function from the package, like this:
它在导入包时在命名空间do_something
内建立函数subpackage
。然后使用test.py
从包中导入函数的a ,如下所示:
from subpackage import do_something
do_something()
A final alternative with the same __init__.py
is to use a test.py
that simply imports the (sub)package and then use relative naming to access the required function:
最后一种替代方法__init__.py
是使用 atest.py
简单地导入(子)包,然后使用相对命名来访问所需的功能:
import subpackage
subpackage.do_something()
to gain access to it in your local namespace
在您的本地命名空间中访问它
With the empty __init__.py
this could also be achieved with a test.py
reading
有了空,__init__.py
这也可以通过test.py
阅读来实现
import subpackage.hello_world
subpackage.hello_world.do_something()
or even
甚至
from subpackage.hello_world import do_something
do_something()
Ultimately the best tool to keep you straight is a clear understanding of how import works and what effect its various forms have on the importing namespace.
最终,让您保持正直的最佳工具是清楚地了解导入的工作原理以及其各种形式对导入命名空间的影响。
回答by evuez
First, you have to understand how import
alone work:
首先,您必须了解import
单独工作的方式:
import test.submodule.do_something
Would try to load do_something
from submodule
itself loaded from test
.
会尝试do_something
从submodule
自身加载从test
.
You want to load something from subpackage
, so start with that:
你想从 加载一些东西subpackage
,所以从它开始:
import subpackage
Fine, subpackage/__init__.py
is loaded.
很好,subpackage/__init__.py
已加载。
Now, you want the do_something()
function which is in the file (a "module") hello_world.py
. Easy:
现在,您需要do_something()
文件(“模块”)中的函数hello_world.py
。简单:
from subpackage.hello_world import do_something
And you are done! Just read this line loud, it does exactly what it says: import do_something
from the module hello_world
which is in the subpackage
package.
你已经完成了!刚读到这响亮,它不正是它说:进口do_something
从模块hello_world
这是在subpackage
包中。
Try that in test.py
试试看 test.py
from subpackage.hello_world import do_something
do_something()
It should work just fine.
它应该工作得很好。
Now, the second issue:
现在,第二个问题:
__init__.py
won't be called in package/
since you don't use package/
as a package. __init__.py
will be used if you do an import of package/
or anything in it, for eg:
__init__.py
不会被调用,package/
因为您不用package/
作包。__init__.py
如果您执行导入package/
或其中的任何操作,将使用,例如:
from package import test
Otherwise, it won't be loaded at all.
否则,它根本不会被加载。
However, if you want to load do_something()
on the import of subpackage, put from submodule.hello_word import do_something
in subpackage/__init__.py
, and then, in you test.py
, do a import subpackage
.
但是,如果你想负载do_something()
上分装的进口,把from submodule.hello_word import do_something
中subpackage/__init__.py
,然后,在你test.py
,做一个import subpackage
。
回答by Daniel Roseman
It's an absolute hard-and-fast rule in Python that a name must always be defined or imported within the module where you're using it. Here you never import anything inside test.py - so as the error says, do_something
is not defined.
在 Python 中,必须始终在使用名称的模块中定义或导入名称,这是绝对的硬性规定。在这里,您永远不会在 test.py 中导入任何内容 - 正如错误所说,do_something
未定义。
Even if your package/__init__.py
file was executed (which, as others have pointed out, it isn't), your code still wouldn't work as it is, because the import of do_something
has to be done inside test.py if you want to reference it in that file.
即使您的package/__init__.py
文件被执行(正如其他人指出的那样,它不是),您的代码仍然无法正常工作,因为do_something
如果您想引用它,则必须在 test.py 中完成导入在那个文件中。