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__变量。

包的用户可以导入包中的单独的某个模块,例如:
import sound.effcts.echo
这会加载子模块sound.effcts.echo,使用时必须使用全名:
sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)

另外一种导入包的方式是:
from sound.effects import echo
这也会加载子模块echo, 使用时不需要使用全名:
echo.echofilter(input, output, delay=0.7, atten=4)

也可以直接导入某个函数:
from sound.effects.echo 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 sound.effects.echo
import sound.effects.surround
from sound.effects import *
在此示例中,echosurround模块被导入当前名称空间中,因为它们在执行语句sound.effects时在包中定义from...import。(这在__all__定义时也适用 。)

尽管某些模块被设计为仅在使用时导出遵循某些模式的名称,但在生产代码中import *仍被认为是不好的做法。

记住,使用from package import specific_submodule没什么错。实际上,这是推荐的表示法,除非导入模块需要使用来自不同软件包的具有相同名称的子模块。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容

  • If you quit from the Python interpreter and enter it agai...
    linyk3阅读 352评论 0 0
  • 如果你从 Python 解释器退出然后再进入它,你所做的定义(函数和变量)都会消失。因此,如果你想写某些更长的程序...
    派派森森阅读 561评论 0 1
  • 用 python 解释器来编程从 Python 解释器退出再进入,那么你定义的所有的方法和变量就都消失了。 为此...
    chen_000阅读 519评论 0 3
  • [译]The Python Tutorial#Modules 6. Modules 如果你从Python解释器中退...
    理查德成阅读 319评论 0 2
  • 在前面的几个章节中我们脚本上是用 python 解释器来编程,如果你从 Python 解释器退出再进入,那么你定义...
    Java丶python攻城狮阅读 292评论 0 0