将代码添加到__init__.py
我正在研究django中的模型系统如何工作,我注意到了一些我不理解的东西。
我知道我们创建了一个空的__init__.py文件来指定当前目录是一个包。并且我们可以在__init __。py
中设置一些变量,以便import *正常工作。
但是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`可以导入任何模块,而不必从包中导入。例如,我们可以将其替换为"导入日期时间",然后在顶层" 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
模块的功能。假设我们不想创建一个名为miscutils
的新模块。 AND,我们希望能够像这样调用该函数:
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)和他们将制成的* Field定义粘贴在fields模块本身中(因此,是__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
从外部看,包装看上去仍然和以前一样。