资讯专栏INFORMATION COLUMN

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

wuyangnju / 3147人阅读

摘要:比如,模块名表示包中名为的子模块。例如,文件可以包含以下代码定义了之后,就会把,,导入到当前命名空间。这种导入使用前导点来指示相对导入中涉及的当前包和父包。也就是说被执行的主程序里面不能包含相对导入。

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

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

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可以包含以下代码:

__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子模块

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

import image

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

image.process.colors(...)

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

import image.process.colors

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

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

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 模块中,你可以使用:

from . import colors
from .. import formats
from ..formats import jpg_read

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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/43796.html

相关文章

  • 当公司辞掉85后测试员选择95后测试员后...

    摘要:反正也考不上了,索性破罐子破摔,大周将自己复习的资料一股脑送给了同战的研友,自己研究起了简历,开始积极迎战校招。 小H被裁员了。 作为一名85后的单身未婚女测试员...

    LiuZh 评论0 收藏0
  • 没什么技术含量的Remove Before Flight

    航空业有很多值得我们借鉴和学习的工作方式,将来有时间我会给大家引荐更多实例。 showImg(https://segmentfault.com/img/remote/1460000013512660?w=680&h=454); 仔细观察每架停泊着的飞机,会发现机身很多地方都挂着细长的红布条,上面写着REMOVE BEFORE FLIGHT,中文翻译成飞行前拆除。这种布条没什么技术含量,但是非常重要...

    wenzi 评论0 收藏0
  • 重磅 | 完备的 AI 学习路线,最详细的资源整理!

    摘要:是你学习从入门到专家必备的学习路线和优质学习资源。的数学基础最主要是高等数学线性代数概率论与数理统计三门课程,这三门课程是本科必修的。其作为机器学习的入门和进阶资料非常适合。书籍介绍深度学习通常又被称为花书,深度学习领域最经典的畅销书。 showImg(https://segmentfault.com/img/remote/1460000019011569); 【导读】本文由知名开源平...

    荆兆峰 评论0 收藏0
  • 记录我的Python学习笔记

    摘要:本文是通过廖雪峰的网站学习而整理的真的是很好的教程,省得我花钱买书了,然后我没有去再整理总结语法,而是直接通过写出代码段来体现自己的学习,也方便以后的快速复习回顾。 不想再像以前那样,什么都从头开始学习语法、总结语法,这样反而会过分纠结于语法,耽误了开发,毕竟语言的主要属性是工具,次要的属性是语言本身。 所以还是先熟练使用语言去进行开发,等足够熟悉了,再去研究语言本身(编译原理……)。...

    lijy91 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<