将代码添加到__init__.py

我正在看django中的模型系统是如何工作的,而且我发现了一些我不明白的东西。

我知道你创build一个空的__init__.py文件来指定当前目录是一个包。 而且你可以在__init__.py设置一些variables,以便导入*正常工作。

但是django增加了一大堆from … import …语句,并在__init__.py定义了一堆类。 为什么? 这不是只是让事情看起来凌乱吗? 是否有一个原因,需要在__init__.py这个代码?

在导入包含它的包(目录)时, __init__.py中的所有导入都可用。

例:

./dir/__init__.py

 import something 

./test.py

 import dir # can now use dir.something 

编辑:忘记提及, __init__.py的代码首次从该目录导入任何模块时运行。 所以通常是放置任何包级初始化代码的好地方。

EDIT2:dgrant在我的例子中指出了可能的混淆。 在__init__.py import something可以导入任何模块,没有必要从包中。 例如,我们可以将其replace为import datetime ,然后在顶层test.py ,这两个片段都可以工作:

 import dir print dir.datetime.datetime.now() 

 import dir.some_module_in_dir print dir.datetime.datetime.now() 

底线是: __init__.py分配的所有名称(无论是导入的模块,函数还是类)都可以在包名称空间中自动使用,无论何时导入包或包中的模块。

这只是个人喜好,而且与你的python模块的布局有关。

假设你有一个叫做erikutils的模块。 有两种方法可以成为一个模块,你可以在你的sys.path上有一个名为erikutils.py的文件,或者你的sys.path有一个名为erikutils的目录,里面有一个空的__init__.py文件。 然后假设你有一堆名为fileutilsprocutilsparseutils的模块,你希望这些模块是erikutils下的子模块。 所以你做一些名为fileutils.pyprocutils.pyparseutils.py的 .py文件:

 erikutils __init__.py fileutils.py procutils.py parseutils.py 

也许你有一些函数不属于fileutilsprocutils或者parseutils模块。 假设您不想创build一个名为miscutils的新模块。 而且,您希望能够像这样调用该函数:

 erikutils.foo() erikutils.bar() 

而不是做

 erikutils.miscutils.foo() erikutils.miscutils.bar() 

所以,因为erikutils模块是一个目录,而不是一个文件,我们必须在__init__.py文件中定义它的函数。

在Django中,我能想到的最好的例子是django.db.models.fields 。 所有的django * Field类都是在django / db / models / fields目录的__init__.py文件中定义的。 我想他们这样做是因为他们不想把所有东西都塞进一个假设的django / db / models / fields.py模型中,所以他们把它分成几个子模块(例如related.pyfiles.py )和他们将制作的*字段定义卡在字段模块本身(因此, __init__.py )。

使用__init__.py文件可以使内部的包结构从外部看不见。 如果内部结构发生变化(例如,因为您将一个胖模块分为两个),则只需调整__init__.py文件,而不是依赖于包的代码。 您也可以使您的软件包的一部分不可见,例如,如果它们尚未准备好用于一般用途。

请注意,您可以使用del命令,因此典型的__init__.py可能如下所示:

 from somemodule import some_function1, some_function2, SomeObject del somemodule 

现在,如果你决定拆分一些somemodule ,新的__init__.py可能是:

 from somemodule1 import some_function1, some_function2 from somemodule2 import SomeObject del somemodule1 del somemodule2 

包装外面看起来还是和以前一样。