• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
qwz185_十秒耿直拆包选手
博客园    首页    新随笔    联系   管理    订阅  订阅
python学习01.04:Python 包

转载:https://www.cnblogs.com/feeland/p/4401758.html

包 定义

  为了组织好模块,会将多个模块分为包。Python 处理包也是相当方便的。简单来说,包就是文件夹,但该文件夹下必须存在 __init__.py 文件。

  常见的包结构如下:

  最简单的情况下,只需要一个空的 __init__.py 文件即可。当然它也可以执行包的初始化代码,或者定义稍后介绍的 __all__ 变量。当然包底下也能包含包,这和文件夹一样,还是比较好理解的。

 

导入包

  包的导入仍使用 import 、 from ... import 语句,使用 “圆点模块名” 的结构化模块命名空间。 下面来看一个包的例子来了解下具体的运作。(官方文档中的例子)

  假设你现在想要设计一个模块集(一个“包”)来统一处理声音文件和声音数据。存在几种不同的声音格式(通常由它们的扩展名来标识,例如: .wav, .aiff, .au )于是,为了在不同类型的文件格式之间转换,你需要维护一个不断增长的包集合。可能你还想要对声音数据做很多不同的操作(例如混音,添加回声,应用平衡 功能,创建一个人造效果)所以你要加入一个无限流模块来执行这些操作。你的包可能会是这个样子(通过分级的文件体系来进行分组):

      

  用户可以每次只导入包里的特定模块,例如: import sound.efforts.echo   这样就导入了 sound.effects.echo 子模块。它必须通过完整的名称来引用:  

1 sound.effects.echo.echofilter(input, output, delay=0.7, atten=4) 

  导入包时有一个可以选择的方式: from sound.effects import echo   这样就加载了 echo 子模块,并且使得它在没有包前缀的情况下也可以使用,所以它可以如下方式调用:  

1 echo.echofilter(input, output, delay=0.7, atten=4) 

      还有另一种变体用于直接导入函数或变量: from sound.effects.echo import echofilter   这样就又一次加载了 echo 字模块,但这样就可以直接调用它的 echofilter() 函数:  

1 echo.echofilter(input, output, delay=0.7, atten=4) 

      注:此处我在测试代码时发现与原blog中不符,下列代码可正常运行。

1 from sound.effects.echo import echofilter
2 echofilter(input, output, delay=0.7, atten=4)

      需要注意的是  from package import item    方式导入包时,这个子项(item)既可以是子包也可以是其他命名,如函数、类、变量等。若无,会引发ImportError异常。

  而用类似 import item.subitem.subsubitem 这样的语法时,这些子项必须是包,最后的子项可以是包或模块,但不能是类、函数、变量等。

测试如下:

要调用的函数信息

 1 # shorten函数在ch04包的test43.py文件中
 2 
 3 
 4 # 测试带有默认参数的函数
 5 def shorten(text, length = 25, indicator = '...'):
 6     """
 7     参数带有默认值的函数
 8     :param text: 文本
 9     :param length: 最大文本长度
10     :param indicator: 缩略
11     :return: 文本
12     """
13     # 字符串超过默认长度
14     if len(text) > length:
15         # 截取字符串,并将字符串返回缩减版
16         text = text[: length - len(indicator)] + indicator
17 
18     print(text)
19     # return text
 

调用函数信息:

 1 # 代码在ch05包的test51.py文件中
 2 # from ch04 import test43
 3 
 4 # 导入方式1,import到最后一个包,调用函数、变量时必须完整名称
 5 # import ch04.test43
 6 # import ch04
 7 # ch04.test43.shorten('hello qiaowei', 9, '***')
 8 # ch04.test43.shorten('hello qiaowei', 9, '***')
 9 
10 # 别名导入
11 # import ch04.test43 as Test
12 # Test.shorten('okkk', 222, '***')
13 
14 # 导入方式2,import到最后一个包,调用时至少要包含最后一个包,才能调用到函数、变量
15 # from ch04 import test43
16 # test43.shorten('qiao shu yi', 9, '---')
17 # ch04.test43.shorten('qiao shu yi', 2, '+++')
18 
19 
20 # 导入方式3,直接import到函数、变量,因为不是完全限定,可能会出现冲突
21 # from ch04.test43 import shorten
22 # shorten('hello zhangchunling', 15, '...')
 

以上代码均可正常运行。

 

从 * 导入包

  import * 这样的语句理论上是希望文件系统找出包中所有的子模块,然后导入它们。这可能会花长时间,并出现边界效应等。Python 解决方案是提供一个明确的包索引。

  这个索引由 __init__.py  定义 __all__ 变量,该变量为一列表,如上例 sound/effects 下的 __init__.py 中,可定义  __all__ = ["echo","surround","reverse"] 

  这意味着,  from sound.effects import *   会从对应的包中导入以上三个子模块; 尽管提供 import * 的方法,仍不建议在生产代码中使用这种写法。

 

包内引用

  如果是子包内的引用,可以按相对位置引入子模块 以 echo 模块为例,可以引用如下:


1 from . import reverse              # 同级目录 导入 reverse
2 from .. import frormats            # 上级目录 导入 frormats
3 from ..filters import equalizer    # 上级目录的filters模块下 导入 equalizer

 

 多重目录包搜索

  包支持一个更为特殊的特性, __path__  在包的 __init__.py 文件代码执行前,该变量初始化一个目录名列表。作用于子包和模块的搜索功能。
  该功能可以用于扩展包中的模块集,不过不常用。

posted on 2021-01-20 19:38  qz185_十秒拆包选手  阅读(87)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3