将代码添加到__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
文件。 然后假设你有一堆名为fileutils
, procutils
, parseutils
的模块,你希望这些模块是erikutils
下的子模块。 所以你做一些名为fileutils.py , procutils.py和parseutils.py的 .py文件:
erikutils __init__.py fileutils.py procutils.py parseutils.py
也许你有一些函数不属于fileutils
, procutils
或者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.py , files.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
包装外面看起来还是和以前一样。