Python - 包的使用详解

微信公众号搜索【程序媛小庄】,关注半路出家的程序媛如何靠python开发养家糊口~

前言

随着模块数目的增多,把所有模块不加区分地放到一起就显得非常不合理了,于是Python为我们提供了一种把模块组织到一起的方法,即创建一个包。

学习包要从两个角度来看,包的设计者包的使用者。因为包是模块,所以包的使用和普通模块的使用方式是一样的。

什么是包

包就是一个包含__init__.py文件的文件夹,文件夹内可以包含子包或者模块,比如创建如下结构的包结构:

package  # 包文件夹
|—— __init__.py
|—— small_package  # 子包文件夹
|   |—— __init__.py
|   |—— module1.py  # 模块文件
|   |—— module2.py  # 模块文件
|——module3.py  # 模块文件

创建包的目的不是为了运行,而是为了被导入使用,包的本质就是模块,因此可以将包当做模块来导入。对于普通模块(一个py文件),会发生三件事,其中一件事就是执行模块文件的代码。包是不能像普通模块那样被执行代码,所以包提供了一个__init__.py文件,导入包就会执行__init__.py文件,这也是__init__.py文件存在的意义。python3中,文件夹没有__init__.py也可以,但是在python2中包必须要有该文件。

如何使用包

以上述包为例,介绍包如何使用,包内各文件代码如下:

# package/module3.py
def test3():
    print('from package/module3')
    
# package/small_package/module1.py
def test1():
    print('package/small_package/module1')
    
# package/small_package/module2.py
def test2():
    print('package/small_package/module2')
    
# __init__.py文件内容均为空

包属于模块的一种,包和包内的模块都是用来被导入使用的,而不是被直接执行,导包就是导入包的__init__.py文件,首次导入包(import package)同样会做三件事:

  1. 执行包的__init__.py文件;

  2. 产生一个名称空间,即__init__.py的名称空间,用于存放__init__.py文件执行过程中产生的名字;

  3. 在当前执行文件所在的名称空间中放一个包的名字,该名字指向__init__.py的名称空间,例如import 包:会将包的__init__.py文件执行一遍,得到的名字都是该__init__.py文件中存在的名字,也就是说包里面的子包或子模块如果不在__init__.py中,是不会被执行的,就不会被导入。

import package

package.module3.test3()  # 会抛出异常AttributeError: module 'package' has no attribute 'module3'

package.module3.test3() 要求package下有名字module3,进而package.module3下有名字test,package.module3下已经有test3了,所以问题就是package下没有名字module3,这就需要在package下的__init__.py中导入模块module3。

包的导入方式和模块相同,分为importfrom ... import ...两种,但是无论以何种方式,无论任何位置,导入时在导入时都必须遵循一个原则:凡是在导入时带点的,点的左边都必须是一个包,否则非法。可以带有一连串的点,如import 顶级包.子包.子模块,但都必须遵循这个原则。但对于导入后,在使用时就没有这种限制了,点的左边可以是包,模块,函数,类(它们都可以用点的方式调用自己的属性)。包A和包B下有同名模块也不会冲突,因为A.a与B.a来自俩个命名空间。

如何设计包

作为包的设计者,需要关注两件事:方便自己组织管理程序;给包的使用者提供便利

首先,方便自己组织管理程序。可以将不同功能的代码放在放在不同的模块(py文件)或者不同的子包(子文件夹)中,这样可以结构清晰的管理组织自己的模块功能。

其次,如何给使用者提供使用包的便利。使用者一般都最求简单的使用方式。所以包的设计者最好将使用方式尽可能设计的简单清晰。因为使用者使用包的方式和使用模块的方式一模一样的,import ... ,或 from....import.... 的方式。不论哪种方式,都会执行模块的程序代码。所以如果是包的话,就需要在__init__.py中隐藏好导入的关系,方便使用者使用。

__init__.py文件模块导入方式

为了方便包的使用者更加方便的使用包,在包的__init__.py文件中可以导入包内的其他模块,分为绝对导入和相对导入。

首先来看绝对导入,绝对导入就是以顶级包作为起始位置进行导入。

# package包的__init__.py

from package.small_package.module1 import test1  # 必须从顶级包开始

import也能使用绝对导入,导入过程中同样会依次执行包下的__init__.py,只是基于import导入的结果,使用时必须加上该一堆前缀。

import package.small_package.module1.test1

package.small_package.module1.test1()

然后来看相对导入,相对导入中.代表当前文件所在目录,..代表当前目录的上一级目录,以此类推。包内模块相互导入只能使用from ... import ... 不能使用import ...,语法错误,包内模块的相互导入推荐使用相对导入。

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

推荐阅读更多精彩内容