将代码添加到__init__.py
-
02-07-2019 - |
题
我正在研究django中的模型系统是如何工作的,我发现了一些我不理解的东西。
我知道您创建了一个空的 __ init __。py
文件来指定当前目录是一个包。并且您可以在 __ init __。py
中设置一些变量,以便导入*正常工作。
但是django添加了一堆来自... import ...语句,并在 __ init __。py
中定义了一堆类。为什么?这不是让事情看起来凌乱吗?是否有理由在 __ init __。py
?
解决方案
导入包含它的包(目录)时, __ init __。py
中的所有导入都可用。
示例:
<代码> ./ DIR / __初始化__吡啶代码>:
import something
<代码> ./ test.py 代码>:
import dir
# can now use dir.something
编辑:忘了提一下,第一次从该目录导入任何模块时, __ init __。py
中的代码运行。所以它通常是放置任何包级初始化代码的好地方。
EDIT2:dgrant在我的例子中指出可能存在混淆。在 __ init __。py
import something
可以导入任何模块,而不需要从包中导入。例如,我们可以用 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 的文件,或者你有一个名为 erikutils <的目录/ em>在 sys.path
上,其中包含一个空的 __ 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
模块。让我们说你不想创建一个名为 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 模型中,所以他们把它分成几个子模块(相关的。 py , files.py ,例如)他们将制作的*字段定义粘贴在字段模块本身中(因此, __ init __。py
的)。
使用 __ init __。py
文件可以使内部包结构从外部不可见。如果内部结构发生更改(例如,因为您将一个fat模块拆分为两个),则只需调整 __ 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
从外面看,包裹看起来仍然和以前完全一样。