python的init⽂件_python的__init__.py⽂件
每当我想搞透⼀个东西的时候,我就会写篇⽂章。OK,今天的主题就是这个__init__⽂件。
关于这个⽂件,问题⽆⾮是三个,是什么,为什么,怎么⽤。
是什么- python包管理
这个问题的核⼼在于python的包管理。
python使⽤包来组织模块的命名空间。A.B表名在A包中的B模块。主要⽤来解决全局变量名称冲突的问题。
为什么
来看⼀个典型的项⽬结构:
image.png
在导⼊⼀个包的时候,python搜索所有sys.path下⾯的⽬录。__init__.py⽂件⽤来告诉python,这个⽬录是⼀个python包。
这个机制防⽌某些通⽤名字的⽬录,例如string,和后续加载的实际可能的模块名发⽣冲突。
怎么⽤
import语句
最简单的情况下,__init__.py⽂件可以是空的。也可以执⾏初始化代码,或者设置__all__变量。
包的⽤户可以导⼊包中的单独的某个模块,例如:
python怎么读取py文件import ho
这会加载⼦模块ho,使⽤时必须使⽤全名:
ho.echofilter(input, output, delay=0.7, atten=4)
另外⼀种导⼊包的⽅式是:
from sound.effects import echo
这也会加载⼦模块echo, 使⽤时不需要使⽤全名:
也可以直接导⼊某个函数:
from ho import echofilter
这会加载⼦模块echo,但是函数echofilter()直接可⽤:
echofilter(input, output, delay=0.7, atten=4)
在使⽤from package import item语法时,item可以是package的⼦模块、⼦包或者任何定义在packge⾥的名字。例如⼀个函数、类或变量。import声明⾸先假设item是package⾥定义的,如果不是,会假设他是⼀个模块并尝试加载。加载失败会抛出importerror.
使⽤import item.subitem.subsubitem的时候,除了嘴后⼀个Item,其他的Item都必须是包。最后⼀个item可以是⼀个模块,⼀个包,但不能是类或者函数、变量。
import * from a package
当⽤户书写from sound.effects import *时会发⽣什么?理想情况下,这种⽅式能进⼊⽂件系统,到
程序包中存在哪些⼦模块,然后将其全部导⼊。这可能会花费很长时间,并且导⼊⼦模块可能会产⽣有害的副作⽤,这些副作⽤只有在明确导⼊⼦模块时才会发⽣。
唯⼀的解决⽅案是让程序包作者提供程序包的显式索引。该import语句使⽤以下约定:如果程序包的 __init__.py代码定义了名为的列表
__all__,则将其视为遇到时应导⼊的模块名称的列表。发⾏新版本的软件包时,软件包作者有责任使此列表保持最新。如果软件包作者看不到从软件包中导⼊*的⽤途,他们可能还会决定不⽀持它。例如,该⽂件可能包含以下代码:
__all__ = ["echo", "surround", "reverse"]
这意味着from sound.effects import *将导⼊sound包的三个命名⼦模块。
如果__all__没有定义,语句 也不会导⼊从包中的所有⼦模块到当前的命名空间; 它仅确保已导⼊包sound.effects(可能运⾏__init__.py中任何初始化代码),然后导⼊包中定义的任何名称。这包括由__init__.py定义的任何名称(以及明确加载的⼦模块)。它还包括程序包的所有⼦模块,这些⼦模块由先前的语句显式加载。考虑以下代码:
import ho
import sound.effects.surround
from sound.effects import *
在此⽰例中,echo和surround模块被导⼊当前名称空间中,因为它们在执⾏语句sound.effects时在包中定义import。(这在
__all__定义时也适⽤ 。)
尽管某些模块被设计为仅在使⽤时导出遵循某些模式的名称,但在⽣产代码中import *仍被认为是不好的做法。
记住,使⽤from package import specific_submodule没什么错。实际上,这是推荐的表⽰法,除⾮导⼊模块需要使⽤来⾃不同软件包的具有相同名称的⼦模块。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。