添加代码的__init__.py(Adding code to __init__.py)

2019-06-26 23:30发布

我考虑看看在Django模型系统是如何工作的,我注意到的东西,我不明白。

我知道你创建一个空的__init__.py文件来指定当前目录是一个包。 而且,你可以设置一些变量中__init__.py使进口*正常工作。

不过在Django中增加了大量来自进口... ...语句并定义了一堆类__init__.py 。 为什么? 这难道不是只会让事情显得凌乱? 是否有需要在此代码的一个原因__init__.py

Answer 1:

在所有进口__init__.py当您导入包含它的包(目录)的提供。

例:

./dir/__init__.py

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 ,无论是进口模块,函数或类,只要你导入的包或包中的一个模块是在包命名空间中自动可用。



Answer 2:

这只是个人喜好确实,与您的Python模块的布局做。

比方说,你有一个模块调用erikutils 。 有两种方法,它可以是一个模块,要么你有一个叫做erikutils.py文件在您sys.path或你有你的一个目录中称为erikutils sys.path有一个空的__init__.py里面的文件。 然后让我们说你有一堆模块调用的fileutilsprocutilsparseutils ,你想那些要承受子模块erikutils 。 所以,你做一些.py文件名为fileutils.py,procutils.pyparseutils.py:

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

也许你有,只是没有在所属的一些功能fileutilsprocutils ,或parseutils模块。 让我们说,你不觉得像创建一个名为新模块miscutils 。 而且,你希望能够调用该函数如下所示:

erikutils.foo()
erikutils.bar()

而不是做

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

所以,因为erikutils模块是一个目录,而不是一个文件,我们要定义它的内部功能__init__.py文件。

在Django,我能想到的最好的例子就是django.db.models.fields 。 *现场类在定义的所有Django的__init__.pyDjango/ DB /模型文件/目录 。 我猜他们这样做是因为他们不希望所有东西都塞进一个假想的Django / DB /模型/ fields.py模式,所以他们分裂出来成几个子模块(related.py,files.py,例如)和他们坚持在字段中取得*字段定义模块本身(因此, __init__.py )。



Answer 3:

使用__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

来自外部的包看上去仍然与之前完全相同。



文章来源: Adding code to __init__.py