Lok*_*oki 1312
它是一个包的一部分.这是文档.
__init__.py
需要这些文件使Python将目录视为包含包; 这样做是为了防止具有通用名称的目录,例如__init__.py
无意中隐藏在模块搜索路径上稍后(更深)发生的有效模块.在最简单的情况下,__init__.py
可以只是一个空文件,但它也可以执行包的初始化代码或设置__init__.py
变量,稍后描述.
car*_*tos 772
命名__init__.py
的文件用于将磁盘上的目录标记为Python包目录.如果你有文件
mydir/spam/__init__.py
mydir/spam/module.py
Run Code Online (Sandbox Code Playgroud)
并且mydir
在您的路径上,您可以将代码导入module.py
为
import spam.module
Run Code Online (Sandbox Code Playgroud)
要么
from spam import module
Run Code Online (Sandbox Code Playgroud)
如果删除该__init__.py
文件,Python将不再查找该目录中的子模块,因此导入模块的尝试将失败.
该__init__.py
文件通常是空的,但可以用更方便的名称导出包的选定部分,保存方便功能等.鉴于上面的例子,init模块的内容可以作为访问
import spam
Run Code Online (Sandbox Code Playgroud)
基于此
Nat*_*uld 458
除了将目录标记为Python包并定义之外__all__
,还__init__.py
允许您在包级别定义任何变量.如果一个包定义了一些经常导入的东西,那么这样做通常会很方便.这种模式促进了对Pythonic的坚持"扁平比嵌套更好"的理念.
以下是我的一个项目中的示例,其中我经常导入一个sessionmaker
被调用Session
来与我的数据库进行交互.我写了一个包含几个模块的"数据库"包:
database/
__init__.py
schema.py
insertions.py
queries.py
Run Code Online (Sandbox Code Playgroud)
我__init__.py
包含以下代码:
import os
from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine
engine = create_engine(os.environ['DATABASE_URL'])
Session = sessionmaker(bind=engine)
Run Code Online (Sandbox Code Playgroud)
由于我Session
在这里定义,我可以使用下面的语法开始一个新的会话.此代码与"database"包目录内部或外部执行的代码相同.
from database import Session
session = Session()
Run Code Online (Sandbox Code Playgroud)
当然,这是一个小小的便利 - 替代方法是Session
在我的数据库包中的新文件中定义"create_session.py",并使用以下命令启动新会话:
from database.create_session import Session
session = Session()
Run Code Online (Sandbox Code Playgroud)
有一个非常有趣的reddit线程,涵盖了__init__.py
这里的适当用法:
http://www.reddit.com/r/Python/comments/1bbbwk/whats_your_opinion_on_what_to_include_in_init_py/
大多数意见似乎是__init__.py
文件应该非常薄,以避免违反"明确比隐含更好"的哲学.
fly*_*cee 204
有两个主要原因 __init__.py
为方便起见:其他用户无需知道函数在包层次结构中的确切位置.
your_package/
__init__.py
file1.py
file2.py
...
fileN.py
Run Code Online (Sandbox Code Playgroud)
其他人可以调用add()
# in __init__.py
from file1 import *
from file2 import *
...
from fileN import *
Run Code Online (Sandbox Code Playgroud)
不知道file1,就像
# in file1.py
def add():
pass
Run Code Online (Sandbox Code Playgroud)如果你想要初始化的东西; 例如,日志记录(应该放在顶层):
from your_package import add
Run Code Online (Sandbox Code Playgroud)Can*_*der 104
该__init__.py
文件使Python将包含它的目录视为模块.
此外,这是要在模块中加载的第一个文件,因此您可以使用它来执行每次加载模块时要运行的代码,或指定要导出的子模块.
zee*_*vfu 80
从Python 3.3开始,__init__.py
不再需要将目录定义为可导入的Python包.
对不需要
__init__.py
标记文件的包目录的本机支持,并且可以自动跨越多个路径段(受各种第三方方法命名空间包的启发,如PEP 420中所述)
这是测试:
$ mkdir -p /tmp/test_init
$ touch /tmp/test_init/module.py /tmp/test_init/__init__.py
$ tree -at /tmp/test_init
/tmp/test_init
??? module.py
??? __init__.py
$ python3
>>> import sys
>>> sys.path.insert(0, '/tmp')
>>> from test_init import module
>>> import test_init.module
$ rm -f /tmp/test_init/__init__.py
$ tree -at /tmp/test_init
/tmp/test_init
??? module.py
$ python3
>>> import sys
>>> sys.path.insert(0, '/tmp')
>>> from test_init import module
>>> import test_init.module
Run Code Online (Sandbox Code Playgroud)
参考:
https
://docs.python.org/3/whatsnew/3.3.html#pep-420-implicit-namespace-packages https://www.python.org/dev/peps/pep-0420/
是__init__. Python 3中的包不是必需的吗?
Mar*_*ton 51
在Python中,包的定义非常简单.与Java一样,层次结构和目录结构是相同的.但你必须有__init__.py
一个包.我将__init__.py
通过以下示例解释该文件:
package_x/
|-- __init__.py
|-- subPackage_a/
|------ __init__.py
|------ module_m1.py
|-- subPackage_b/
|------ __init__.py
|------ module_n1.py
|------ module_n2.py
|------ module_n3.py
Run Code Online (Sandbox Code Playgroud)
__init__.py
可以是空的,只要它存在.它表示该目录应被视为包.当然,__init__.py
也可以设置相应的内容.
如果我们在module_n1中添加一个函数:
def function_X():
print "function_X in module_n1"
return
Run Code Online (Sandbox Code Playgroud)
运行后:
>>>from package_x.subPackage_b.module_n1 import function_X
>>>function_X()
function_X in module_n1
Run Code Online (Sandbox Code Playgroud)
然后我们按照层次结构包并调用module_n1函数.我们可以__init__.py
在subPackage_b中使用这样的:
__all__ = ['module_n2', 'module_n3']
Run Code Online (Sandbox Code Playgroud)
运行后:
>>>from package_x.subPackage_b import *
>>>module_n1.function_X()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named module_n1
Run Code Online (Sandbox Code Playgroud)
因此,使用*导入,模块包受__init__.py
内容限制.
Sim*_*mon 47
虽然Python在没有__init__.py
文件的情况下工作,但您仍应包含一个.
它指定一个包应该被视为一个模块,因此包括它(即使它是空的).
还有一种情况您可能实际使用__init__.py
文件:
想象一下,您有以下文件结构:
main_methods
|- methods.py
Run Code Online (Sandbox Code Playgroud)
而methods.py
包含在此:
def foo():
return 'foo'
Run Code Online (Sandbox Code Playgroud)
要使用,foo()
您需要以下之一:
from main_methods.methods import foo # Call with foo()
from main_methods import methods # Call with methods.foo()
import main_methods.methods # Call with main_methods.methods.foo()
Run Code Online (Sandbox Code Playgroud)
也许你需要(或想要)保持methods.py
在内部main_methods
(例如运行时/依赖)但你只想导入main_methods
.
如果更改的名称methods.py
来__init__.py
那么你可以使用foo()
由只导入main_methods
:
import main_methods
print(main_methods.foo()) # Prints 'foo'
Run Code Online (Sandbox Code Playgroud)
这是有效的,因为__init__.py
它被视为包的一部分.
一些Python包实际上是这样做的.一个例子是使用JSON,其中运行import json
实际上是__init__.py
从json
包中导入的(请参阅此处的包文件结构):
源代码:
Lib/json/__init__.py
B.M*_*.W. 38
__init__.py
将它所在的目录视为可加载模块.
对于喜欢阅读代码的人,我在这里提出了Two-Bit Alchemist的评论.
$ find /tmp/mydir/
/tmp/mydir/
/tmp/mydir//spam
/tmp/mydir//spam/__init__.py
/tmp/mydir//spam/module.py
$ cd ~
$ python
>>> import sys
>>> sys.path.insert(0, '/tmp/mydir')
>>> from spam import module
>>> module.myfun(3)
9
>>> exit()
$
$ rm /tmp/mydir/spam/__init__.py*
$
$ python
>>> import sys
>>> sys.path.insert(0, '/tmp/mydir')
>>> from spam import module
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named spam
>>>
Run Code Online (Sandbox Code Playgroud)
Epi*_*aph 29
它有助于导入其他python文件.当您将此文件放在包含其他py文件的目录(比如说东西)中时,您可以执行import stuff.other之类的操作.
root\
stuff\
other.py
morestuff\
another.py
Run Code Online (Sandbox Code Playgroud)
如果没有这个__init__.py
目录内容,你就无法导入other.py,因为Python不知道东西的源代码在哪里,也无法将其识别为包.
An __init__.py
file makes imports easy. When an __init__.py
is present within a package, function a()
can be imported from file b.py
like so:
from b import a
Run Code Online (Sandbox Code Playgroud)
Without it, however, you can't import directly. You have to amend the system path:
import sys
sys.path.insert(0, 'path/to/b.py')
from b import a
Run Code Online (Sandbox Code Playgroud)
__init__.py 允许的一件事是将模块转换为包,而不会破坏 API 或创建无关的嵌套命名空间或私有模块*。当我想扩展命名空间时这会很有帮助。
如果我有一个文件 util.py 包含
def foo():
...
Run Code Online (Sandbox Code Playgroud)
然后用户将foo
访问
from util import foo
Run Code Online (Sandbox Code Playgroud)
如果我想添加用于数据库交互的实用程序函数,并且我希望它们在 下有自己的命名空间util
,我将需要一个新目录**,并保持 API 兼容性(以便from util import foo
仍然有效),我将调用它实用程序/。我可以像这样将 util.py 移动到 util/ 中,
def foo():
...
Run Code Online (Sandbox Code Playgroud)
并在 util/__init__.py 中执行
from util import *
Run Code Online (Sandbox Code Playgroud)
但这是多余的。我们可以将 util.py 内容放入 __init__.py 中,而不是使用 util/util.py 文件,用户现在可以
from util import foo
from util.db import check_schema
Run Code Online (Sandbox Code Playgroud)
我认为这很好地突出了包的 __init__.py 如何以与模块util
类似的方式运行util
* 这在其他答案中有所暗示,但我想在这里强调它
** 缺少使用进口体操。请注意,创建与文件同名的新包将不起作用,请参阅此