Python源目录中的__init__.py是什么?


#1楼

除了将目录标记为Python包并定义__all____init__.py允许您在包级别定义任何变量。 如果程序包定义了将以类似于API的方式频繁导入的内容,则这样做通常很方便。 这种模式促进了对Pythonic的“扁平优于嵌套”哲学的坚持。

一个例子

这是我的一个项目的示例,在该项目中,我经常导入一个名为Sessionsessionmaker来与数据库进行交互。 我写了一个带有一些模块的“数据库”包:

database/__init__.pyschema.pyinsertions.pyqueries.py

我的__init__.py包含以下代码:

import osfrom sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engineengine = create_engine(os.environ['DATABASE_URL'])
Session = sessionmaker(bind=engine)

由于我在此处定义Session ,因此可以使用以下语法开始新的会话。 此代码将从“数据库”包目录的内部或外部执行相同。

from database import Session
session = Session()

当然,这很方便-替代方法是在数据库包中的新文件(例如“ create_session.py”)中定义Session ,然后使用以下命令启动新的会话:

from database.create_session import Session
session = Session()

进一步阅读

这里有一个非常有趣的reddit线程,涵盖了__init__.py适当用法:

http://www.reddit.com/r/Python/comments/1bbbwk/whats_your_opinion_on_what_to_include_in_init_py/

大多数人似乎认为__init__.py文件应该很薄,以避免违反“显式优于隐式”的哲学。


#2楼

在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

__init__.py可以为空,只要它存在。 它指示该目录应视为一个包。 当然, __init__.py也可以设置适当的内容。

如果我们在module_n1中添加一个函数:

def function_X():print "function_X in module_n1"return

运行后:

>>>from package_x.subPackage_b.module_n1 import function_X
>>>function_X()function_X in module_n1

然后,我们遵循层次结构包,并将module_n1称为函数。 我们可以这样在subPackage_b中使用__init__.py

__all__ = ['module_n2', 'module_n3']

运行后:

>>>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

因此,使用*导入,模块包受__init__.py内容约束。


#3楼

__init__.py会将其所在的目录视为可加载模块。

对于喜欢阅读代码的人,我在这里添加了两位炼金术士的评论。

$ 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
>>>

#4楼

__init__.py有两个主要原因

  1. 为方便起见:其他用户将不需要知道您的函数在包层次结构中的确切位置。

     your_package/ __init__.py file1.py file2.py ... fileN.py 
     # in __init__.py from file1 import * from file2 import * ... from fileN import * 
     # in file1.py def add(): pass 

    然后其他人可以通过以下方式调用add()

     from your_package import add 

    不知道file1,例如

     from your_package.file1 import add 
  2. 如果您想初始化一些东西; 例如,日志记录(应放在顶层):

     import logging.config logging.config.dictConfig(Your_logging_config) 

#5楼

从Python 3.3开始,不再需要__init__.py来将目录定义为可导入的Python包。

检查PEP 420:隐式命名空间包 :

对不需要__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

参考资料:
https://docs.python.org/3/whatsnew/3.3.html#pep-420-implicit-namespace-packages
https://www.python.org/dev/peps/pep-0420/
Python 3中的软件包是否不需要__init__.py?


#6楼

名为__init__.py文件用于将磁盘上的目录标记为Python软件包目录。 如果您有文件

mydir/spam/__init__.py
mydir/spam/module.py

并且mydir在您的路径上,您可以将module.py的代码导入为

import spam.module

要么

from spam import module

如果删除__init__.py文件,Python将不再在该目录中查找子模块,因此尝试导入该模块将失败。

__init__.py文件通常为空,但可用于以更方便的名称导出包的选定部分,保留方便的函数等。给定上面的示例,可以按以下方式访问init模块的内容:

import spam

基于此


#7楼

它曾经是软件包的必需部分( 旧的3.3之前的“常规软件包” ,而不是新的3.3+“命名空间软件包” )。

这是文档。

Python定义了两种类型的程序包,常规程序包和名称空间程序包。 常规软件包是Python 3.2及更早版本中存在的传统软件包。 常规软件包通常实现为包含__init__.py文件的目录。 导入常规程序包时,将隐式执行此__init__.py文件,并将其定义的对象绑定到程序包名称空间中的名称。 __init__.py文件可以包含任何其他模块可以包含的相同Python代码,并且在导入时Python将向该模块添加一些其他属性。

但是只需单击链接,它包含一个示例,更多信息以及名称空间包的说明,即不带__init__.py的包的类型。


#8楼

它有助于导入其他python文件。 当您将此文件放置在包含其他py文件的目录中(例如,东西)时,可以执行诸如import stuff.other之类的操作。

root\stuff\other.pymorestuff\another.py

如果在目录东西中没有这个__init__.py ,您将无法导入other.py,因为Python不知道东西的源代码在哪里,也无法将其识别为包。


#9楼

__init__.py文件使Python将包含它的目录视为模块。

此外,这是要在模块中加载的第一个文件,因此您可以使用它来执行每次加载模块时要运行的代码,或指定要导出的子模块。


#10楼

尽管Python在没有__init__.py文件的情况下仍可工作,但您仍应包含一个。

它指定应将程序包视为模块,因此将其包括在内(即使它为空)。

在某些情况下,您实际上可能会使用__init__.py文件:

假设您具有以下文件结构:

main_methods |- methods.py

methods.py包含以下内容:

def foo():return 'foo'

要使用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()

也许您需要(或想要)将methods.py保留在main_methods (例如,运行时/依赖项),但是您只想导入main_methods


如果将methods.py的名称更改为__init__.py则可以通过导入main_methods来使用foo()

import main_methods
print(main_methods.foo()) # Prints 'foo'

之所以__init__.py是因为__init__.py被视为程序包的一部分。


一些Python软件包实际上是这样做的。 以JSON为例,其中运行import json实际上是从json包中导入__init__.py . json ( 请参见此处的包文件结构 ):

源代码: Lib/json/__init__.py


#11楼

__init__.py文件使导入变得容易。 当包中包含__init__.py ,可以从文件b.py导入函数a()b.py所示:

from b import a

但是,没有它,您将无法直接导入。 您必须修改系统路径:

import sys
sys.path.insert(0, 'path/to/b.py')from b import a

__init__.py的作用是什么?相关推荐

  1. python的init有什么用_Python中 __init__.py的作用

    我们经常在python的模块目录中会看到 "__init__.py"  这个文件,那么它到底有什么作用呢? 1. 标识该目录是一个python的模块包(module package ...

  2. Python中 __init__.py的作用

    我们经常在python的模块目录中会看到 __init__.py 这个文件,那么它到底有什么作用呢? 1.标识该目录是一个python的模块包(module package) 如果你是使用python ...

  3. Python杂谈: __init__.py的作用

    我们经常在python的模块目录中会看到 "__init__.py"  这个文件,那么它到底有什么作用呢? 1. 标识该目录是一个python的模块包(module package ...

  4. Python的__init__.py文件作用

    今天在运行pytest命令的时候遇到报错,试过很多种方法,也没解决.后来才发现原来是无意中删除了__init__.py文件,python虚拟机觉得不是合法的包,导致不能识别而报错.添加之后再运行,果然 ...

  5. python入门须知:包、模块、库的含义以及导入以及包下__init__.py的作用

    概念 包:(Package) 包:是一个有层级的目录结构,包含n个模块或者n个子包,包中一定要有__init__.py文件,所以包只是一个组织方式,更加有条理,并不是必须的. 模块:(Module) ...

  6. python __init__.py的作用是什么?

    它曾经是程序包的必需部分(旧的3.3之前的"常规程序包",而不是较新的3.3+"命名空间程序包"). 这是文档. Python定义了两种类型的程序包,常规程序包 ...

  7. python文件夹中的__init__.py的作用

    一个目录如果包含了__init__.py文件,那么他就变成了一个包(package). __init__可以是空的,但是必须存在,其他程序才能从这个目录中导入相应的模块或函数. 例如data文件夹下有 ...

  8. python中__init__.py的作用、module和package

    控制包的导入行为: 1.声明当前文件是一个可导入的包: 2.如果当下包下有多个.py文件使用__ all__ = [ '模块名'],也就是form XXX import YYY module和pack ...

  9. python教程--__init_.py的作用

    __init__.py 的作用 python的每个模块的包中,都有一个__init__.py文件,有了这个文件,我们才能导入这个目录下的module. 那么,__init__.py还有什么别的功能呢? ...

最新文章

  1. ThinkPHP5整合LayUI编辑器图片上传
  2. 听说,霸都.NET技术社区准备搞线下聚会了?
  3. stream获取filter
  4. 魅族魅蓝max简单打开USB调试模式的经验
  5. 朋友圈句句刺痛人心的唯美句子有哪些
  6. php 0 n随机数,PHP n个不重复的随机数生成代码
  7. 中小企业应该将云存储用于主数据吗?
  8. apache 支持.htaccess 解决Internal Server Error The server 错误
  9. 使用python多进程批量转换word为PDF
  10. 中国区块链第一辩 | 老冒:区块链3.0应该让应用变得跟Web一样简单
  11. win10连接dns服务器未响应,win10提示dns服务器未响应怎么解决_win10网络诊断为dns未响应修复方法...
  12. VMware虚拟机无网络
  13. GCJ-02和BD-09互转、GCJ-02和WGS-84互转
  14. visdom远程连接服务器
  15. 利用Lambda表达式从实体集合中筛选出符合条件的实体集合
  16. GIF转MP4 - 在线将GIF动态图转为MP4视频文件
  17. 我们应该怎样看待经济危机
  18. Java学习笔记Day02
  19. mybatis-plus 有了这只小鸟,从此告别加班福报
  20. 《队长说得队》第三次作业:团队项目的原型设计

热门文章

  1. angular启动过程分析
  2. 2006毕业设计Delphi篇(二)
  3. kafka基本概念和hello world搭建
  4. 4.7清明考试(完蛋)
  5. 解决 Chrome 请停用以开发者模式运行的扩展程序
  6. android AsyncTask 只能在线程池里单个运行的问题
  7. Word两端对齐问题
  8. ELK logstash 处理MySQL慢查询日志
  9. CentOS 7.4救援模式和忘记root密码
  10. 天云服务器做系统,自己做云服务器系统