前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python基础教程:包,对,没错,绝对不是双肩包!

python基础教程:包,对,没错,绝对不是双肩包!

作者头像
一墨编程学习
发布2019-05-15 14:11:23
4830
发布2019-05-15 14:11:23
举报

包,Package,是一种Python模块的集合,从文件组织形式上看,包就是一个文件夹,里面放着各种模块(.py文件),也可以有子文件夹(子包)。包名构建了一个Python模块的命名空间。比如,模块名A.B表示A包中名为B的子模块。这种使用加点的模块名可以让你写的软件包里面的模块名称和其它软件包里面的模块名称一样,但又不相互冲突。

举个栗子,我们要设计一个处理图片的模块集合(一个包)。我们知道,图片有多种不同的文件格式,一般它们以不同的扩展名来识别,比如.jpg.png.gif等等。为了读写不同格式的图片,你需要对每一种格式建立一个对应的模块进行处理,为了支持更多的图片格式,你就要增加更多对应的模块。对于图片你可能还有更多的处理,比如,改变色彩,裁剪,旋转等等,为了实现这些功能,你又要写更多的模块。这样下来,你的包的结构以文件系统的形式表示如下:

代码语言:javascript
复制
image            # 顶级包
├── __init__.py  # 初始化image包
├── formats      # 图片格式的子包
│   ├── gif_read.py
│   ├── gif_write.py
│   ├── __init__.py
│   ├── jpg_read.py
│   ├── jpg_write.py
│   ├── png_read.py
│   └── png_write.py
└── process      # 图片处理的子包
    ├── colors.py
    ├── crop.py
    ├── __init__.py
    └── rotate.py

为了让目录成为Python的包,目录中必须含有一个__init__.py文件,它可以是空文件但不能不存在。这样做的目的是为了仿照具有通用名称的目录无意中隐藏了在模块搜索路径排在后面的有效模块。比如,你当前目录下有个time目录是放程序资源的,它里面没有__init__.py文件就是一个普通的目录。如果Python不要求包目录下必须含有__init__.py文件,它就会隐藏Python系统的time模块。

all变量

前面说了,包的目录中必须包含一个__init__.py文件,它可以是空文件,也可以写包初始化相关的代码,或者定义__all__变量。

__all__变量是一个列表,它列举了这个包包含的子模块的名称。当from package import *语句执行时,会把这个模块名称列表里面的模块名称导入。所以说__all__是一个包的显示索引。如果你觉得从包中导入*的操作没必要被使用,也可以不定义__all__这个变量。

例如,文件image/process/init.py可以包含以下代码:

代码语言:javascript
复制
__all__ = ['colors', 'crop', 'rotate']

定义了__all__之后,from image.process import *就会把colorscroprotate导入到当前命名空间。

实际写代码的实践中,import *的做法是严格被禁止的,它容易造成包中模块名与当前命名空间的名称冲突。

更推荐的方法是from package import submodulefrom package import submodule as alias_for_submodule。当然,如果两个包中有同名的submodule,就不能同时使用from package import submodule,但可以取个别名。

导入Python包或Python子模块

导入包的方法和导入模块的方法一样:

代码语言:javascript
复制
import image

在程序中引用colors子模块时:

代码语言:javascript
复制
image.process.colors(...)

接下来,看看我们如何导入一个包中某单个模块:

代码语言:javascript
复制
import image.process.colors

这样就加载了子模块image.process.colors,在程序中使用时必须使用它的全名,而不是简单的colors

如果想使用colors这个名字,就用这种导入语句:

代码语言:javascript
复制
from image.process import colors

Python子包参考

当包含有子包时(与例子中的image包类似),我们可以使用绝对导入来引用兄弟包的子模块。比如,如果模块 image.process.crop 需要使用 image.formats 包中的 jpg_read 模块时,它可以使用 from image.formats import jpg_read

我们也可以使用 from module import name的形式相对导入。这种导入使用前导点.来指示相对导入中涉及的当前包父包。比如,在 crop 模块中,你可以使用:

代码语言:javascript
复制
from . import colors
from .. import formats
from ..formats import jpg_read

请主要,相对导入是基于当前模块的名字进行导入的。由于主模块(即被python 执行的那个.py文件)的名称总是"__main__",因此用作Python应用程序的主模块的模块必须用绝对导入。也就是说被执行的主程序里面不能包含相对导入。这一点很重要,切记!

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019.05.11 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • all变量
  • 导入Python包或Python子模块
  • Python子包参考
相关产品与服务
图片处理
图片处理(Image Processing,IP)是由腾讯云数据万象提供的丰富的图片处理服务,广泛应用于腾讯内部各产品。支持对腾讯云对象存储 COS 或第三方源的图片进行处理,提供基础处理能力(图片裁剪、转格式、缩放、打水印等)、图片瘦身能力(Guetzli 压缩、AVIF 转码压缩)、盲水印版权保护能力,同时支持先进的图像 AI 功能(图像增强、图像标签、图像评分、图像修复、商品抠图等),满足多种业务场景下的图片处理需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档