《Python进阶系列》一:使用Python包组织代码

2023-10-30

使用Python包(package)组织代码

最近在看 Python入门技能树 时,看到了Python包组织代码觉得很有意思,特地写个笔记总结一下。
\quad

Python 通过包(package)的方式来组织代码,包是一种特殊的模块(module)。

Python 的包有两种形式,分别是Regular packages 和 namespace packages。

所谓 Regular packages 就是指含有__init__.py的目录,这样的包被其他模块导入的时候,会先执行目录下__init__.py里的代码。Regular packages 可以嵌套,也就是目录下的子目录也可以是一个包。

一、前期准备

假设parent/__init__.py里的代码是:

print('从前有座山,')

假设parent/one/__init__.py里的代码是:

print('山上有座庙,')

假设parent/one/one/__init__.py里的代码是:

print('庙里有个老和尚,')

假设parent/two/__init__.py里的代码是:

print('老和尚说:')

假设parent/three/__init__.py里的代码是:

print('从前有座山,')

按上述所示建立对于的py文件。对应效果如下图所示。
在这里插入图片描述
具体文件内容对应如下:

# |-parent:
# |---print('从前有座山,')
# |---one:
# |-------print('山上有座庙,')
# |-------one:
# |-----------print('庙里有个老和尚,')
# |---two:
# |-------print('老和尚说:')
# |---three:
# |-------print('从前有座山,')

二、多种import调用方法

如果一个模块被import过,Python会将导入的模块缓存在sys.modules字典里缓存起来,再次导入的时候不会重新执行导入动作,直接从缓存里取。反之,如果我们从sys.modules里把导入的模块删除,则再次import会再次触发模块导入动作。

先来介绍一下del:python中的del用于删除对应的变量的引用。由于python都是引用,而python有GC机制,所以,del语句作用在变量上,而不是数据对象上。

if __name__ == '__main__':
    a = 1  # 对象 1 被 变量a引用,对象1的引用计数器为1
    b = a  # 对象1 被变量b引用,对象1的引用计数器加1
    c = a  # 1对象1 被变量c引用,对象1的引用计数器加1
    del a  # 删除变量a,解除a对1的引用
    del b  # 删除变量b,解除b对1的引用
    print(c)  # 最终变量c仍然引用1

一句话来说,就是del删除的是变量,而不是数据

实验

if __name__ == '__main__':
    while True:
        import parent.one.one

# 从前有座山,
# 山上有座庙,
# 庙里有个老和尚,

import parent.one.one操作会同时打印三个__init__.py的内容。

if __name__ == '__main__':
    while True:
        import parent.one.one
        import parent.two

# 从前有座山,
# 山上有座庙,
# 庙里有个老和尚,
# 老和尚说:

这是因为Python会将导入的模块缓存在sys.modules字典里缓存起来,再次导入的时候不会重新执行导入动作,直接从缓存里取。所以只有一次打印输出。

if __name__ == '__main__':
    while True:
        import parent.one.one

        del sys.modules['parent.one.one']

# 从前有座山,
# 山上有座庙,
# 庙里有个老和尚,
# 庙里有个老和尚,
# 庙里有个老和尚,
# ...

这是因为在把'parent.one.one'sys.modules里把导入的模块删除,则再次import会再次触发模块导入动作。

所以要实现循环输出对应内容,需要在每一次循环中把导入的模块都一一删除,这样才能循环起来!
\quad
\quad


\quad
\quad
Task:利用以上知识,我们的目标是通过 import 语句导入模块,触发每个包目录下__init__.py加载时执行print语句,从而循环打印出:

从前有座山,
山上有座庙,
庙里有个老和尚,
老和尚说:
从前有座山,
山上有座庙,
庙里有个老和尚,
老和尚说:
从前有座山,
...

知道了上述知识和实验之后,这就很简单了!

第一种写法

import sys

if __name__ == '__main__':
    while True:
        import parent.one.one
        import parent.two
        import parent

        del sys.modules['parent.one']
        del sys.modules['parent.one.one']
        del sys.modules['parent.two']
        del sys.modules['parent']

第二种写法

import sys

if __name__ == '__main__':
    while True:
        import parent.one.one
        import parent.two
        del sys.modules['parent']
        del sys.modules['parent.one']
        del sys.modules['parent.one.one']
        del sys.modules['parent.two']

第三种写法

import sys

if __name__ == '__main__':
    while True:
        import parent
        import parent.one
        import parent.one.one
        import parent.two

        del sys.modules['parent']
        del sys.modules['parent.one']
        del sys.modules['parent.one.one']
        del sys.modules['parent.two']

参考

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

《Python进阶系列》一:使用Python包组织代码 的相关文章

  • 使用 python 进行串行数据记录

    Intro 我需要编写一个小程序来实时读取串行数据并将其写入文本文件 我在读取数据方面取得了一些进展 但尚未成功地将这些信息存储在新文件中 这是我的代码 from future import print function import se
  • python 中的代表

    我实现了这个简短的示例来尝试演示一个简单的委托模式 我的问题是 这看起来我已经理解了委托吗 class Handler def init self parent None self parent parent def Handle self
  • if 语句未命中中的 continue 断点

    在下面的代码中 两者a and b是生成器函数的输出 并且可以评估为None或者有一个值 def testBehaviour self a None b 5 while True if not a or not b continue pri
  • Argparse nargs="+" 正在吃位置参数

    这是我的解析器配置的一小部分 parser add argument infile help The file to be imported type argparse FileType r default sys stdin parser
  • Pandas 中允许重复列

    我将一个大的 CSV 包含股票财务数据 文件分割成更小的块 CSV 文件的格式不同 像 Excel 数据透视表之类的东西 第一列的前几行包含一些标题 公司名称 ID 等在以下列中重复 因为一家公司有多个属性 而不是一家公司只有一栏 在前几行
  • 忽略 Mercurial hook 中的某些 Mercurial 命令

    我有一个像这样的善变钩子 hooks pretxncommit myhook python path to file myhook 代码如下所示 def myhook ui repo kwargs do some stuff 但在我的例子中
  • Pandas 数据帧到 numpy 数组 [重复]

    这个问题在这里已经有答案了 我对 Python 很陌生 经验也很少 我已经设法通过复制 粘贴和替换我拥有的数据来使一些代码正常工作 但是我一直在寻找如何从数据框中选择数据 但无法理解这些示例并替换我自己的数据 总体目标 如果有人真的可以帮助
  • TensorFlow的./configure在哪里以及如何启用GPU支持?

    在我的 Ubuntu 上安装 TensorFlow 时 我想将 GPU 与 CUDA 结合使用 但我却停在了这一步官方教程 http www tensorflow org get started os setup md 这到底是哪里 con
  • 如何解决使用 Spark 从 S3 重新分区大量数据时从内存中逐出缓存的表分区元数据的问题?

    在尝试从 S3 重新分区数据帧时 我收到一个一般错误 Caused by org apache spark SparkException Job aborted due to stage failure Task 33 in stage 1
  • 如何设置 Celery 来调用自定义工作器初始化?

    我对 Celery 很陌生 我一直在尝试设置一个具有 2 个独立队列的项目 一个用于计算 另一个用于执行 到目前为止 一切都很好 我的问题是执行队列中的工作人员需要实例化一个具有唯一 object id 的类 每个工作人员一个 id 我想知
  • 将 matplotlib 颜色图集中在特定值上

    我正在使用 matplotlib 颜色图 seismic 绘制绘图 并且希望白色以 0 为中心 当我在不进行任何更改的情况下运行脚本时 白色从 0 下降到 10 我尝试设置 vmin 50 vmax 50 但在这种情况下我完全失去了白色 关
  • 在 pytube3 中获取 youtube 视频的标题?

    我正在尝试构建一个应用程序来使用 python 下载 YouTube 视频pytube3 但我无法检索视频的标题 这是我的代码 from pytube import YouTube yt YouTube link print yt titl
  • 如何在 python 中没有 csv.reader 迭代器的情况下解析单行 csv 字符串?

    我有一个 CSV 文件 需要重新排列和重新编码 我想跑 line line decode windows 1250 encode utf 8 在由 CSV 读取器解析和分割之前的每一行 或者我想自己迭代行 运行重新编码 并仅使用单行解析表单
  • mac osx 10.8 上的初学者 python

    我正在学习编程 并且一直在使用 Ruby 和 ROR 但我觉得我更喜欢 Python 语言来学习编程 虽然我看到了 Ruby 和 Rails 的优点 但我觉得我需要一种更容易学习编程概念的语言 因此是 Python 但是 我似乎找不到适用于
  • Tkinter - 浮动窗口 - 调整大小

    灵感来自this https stackoverflow com a 22424245 13629335问题 我想为我的根窗口编写自己的调整大小函数 但我刚刚注意到我的代码显示了一些性能问题 如果你快速调整它的大小 你会发现窗口没有像我希望
  • 当鼠标悬停在上面时,intellisense vscode 不显示参数或文档

    我正在尝试将整个工作流程从 Eclipse 和 Jupyter Notebook 迁移到 VS Code 我安装了 python 扩展 它应该带有 Intellisense 但它只是部分更糟糕 我在输入句点后收到建议 但当将鼠标悬停在其上方
  • 在Python中按属性获取对象列表中的索引

    我有具有属性 id 的对象列表 我想找到具有特定 id 的对象的索引 我写了这样的东西 index 1 for i in range len my list if my list i id specific id index i break
  • 检查字典键是否有空值

    我有以下字典 dict1 city name yass region zipcode phone address tehsil planet mars 我正在尝试创建一个基于 dict1 的新字典 但是 它不会包含带有空字符串的键 它不会包
  • 迭代 pandas 数据框的最快方法?

    如何运行数据框并仅返回满足特定条件的行 必须在之前的行和列上测试此条件 例如 1 2 3 4 1 1 1999 4 2 4 5 1 2 1999 5 2 3 3 1 3 1999 5 2 3 8 1 4 1999 6 4 2 6 1 5 1
  • 您可以使用关键字参数而不提供默认值吗?

    我习惯于在 Python 中使用这样的函数 方法定义 def my function arg1 None arg2 default do stuff here 如果我不供应arg1 or arg2 那么默认值None or default

随机推荐

  • ChatGPT写小论文

    ChatGPT写小论文 只是个人对写小论文心得 从知乎 知网自己总结的 有问题 可以留个言我改一下 别删我的东西啊CSDN 文章目录 ChatGPT写小论文 1 写小论文模仿实战 狗头 0 小论文组成 1 好论文前提 2 标题 3 摘要 4
  • Transformer(三)--论文实现:transformer pytorch 代码实现

    转载请注明出处 https blog csdn net nocml article details 124489562 本系列传送门 Transformer 一 论文翻译 Attention Is All You Need 中文版 Tran
  • games101笔记 Shading

    什么是shading 不同的物体应用不同的材质的过程 就是计算出物体具体应该在的地方 物体的光照 物体本身应该有的材质 Blinn Phong Reflectance Model Blinn Phong反射模型 Blinn Phong Re
  • MySql执行顺序及执行计划

    一 mySql的执行顺序 mysql执行sql的顺序从 From 开始 以下是执行的顺序流程 1 FROM table1 left join table2 on 将table1和table2中的数据产生笛卡尔积 生成Temp1 2 JOIN
  • Spring和springMVC启动流程

    首先Spring是建立在Servlet容器之上的 所有web工程的初始位置都是在web xml文件中 它配置了servlet的上下文 context 和监听器 listener spring的启动过程其实就是ioc的启动过程 1 首先初始化
  • linux下出现ping:unknown host www.baidu.com问题时的解决办法——ubuntu下局域网络的配置

    如果ping域名的时候出现ping unknown host xxx xxx 但是ping IP地址的时候可以通的话 可知是dns服务器没有配置好 查看一下配置文件 etc resolv conf 里面是否有nameserver xxx x
  • 算力和硬件的关系_算力就是生产力:中国AI算力占全球三成

    12月15日 IDC与浪潮集团联合发布了 2020 2021中国人工智能计算力发展评估报告 报告从旨在评估中国人工智能发展的现状 为推动产业AI化发展提供极具价值的参考依据和行动建议 据报告显示 预计2020 年中国AI市场规模将达到 62
  • chatgpt(0)-pycharm-vscode安装使用插件Codeium-bito

    1 pycharm codeium 下载插件 codeium 登录 一直出现 Log In Codeium Free AI Code Completion Chat 2 pycharm bito 3 vscode bito 下载安装 注册登
  • 十六进制加法

    十六进制加法逢16进1位 注意 进位的那个位是 和 16 举例 0x21 0x3F 60 而不是 0x21 0x3F 6F
  • Proguard混淆工具使用方法图文说明

    Proguard的理论知识请看这篇文章 http www cnblogs com cr330326 p 5534915 html 1 下载Proguard 官网地址 http proguard sourceforge net 不墙很难打开
  • Sonar代码质量管理

    一 简介 1 1 什么是Sonar Sonar是一个用于代码质量管理的开源平台 用于管理代码的质量 是一个Web系统 展现了静态代码扫描的结果 通过插件形式可以支持二十几种语言的代码质量检测 通过多个维度的检查了快速定位代码中潜在的或者明显
  • fopen 参数'rb' 与'rb+'引发的黑色血案

    目录 一 背景 二 代码说明 1 下面是出错的代码 2 如何变正常的 三 问题分析 1 关于rb与rb 的区别 2 关于fread的两种形式说明 3 原因分析 一 背景 为了把windows上的算法库移植到linux上 文件读写部分去掉了C
  • IO流(异常的处理)

    IO流 概述 IO流 又叫输入输出流 当我们将内存中的数据写到硬盘上时 这个过程叫输出流 Output 当我们将硬盘上的数据读取到内存中时 叫做输入流 Input 流本身是一个抽象概念 是 对数据传输的总称 也就是说 数据在设备键的传输 叫
  • 跟李沐学AI之注意力机制+transformer

    注意力机制 注意力提示 注意力的可视化 注意力汇聚 平均汇聚 非参数注意力汇聚 带参数注意力汇聚 注意力评分函数 掩蔽softmax操作 加性注意力 缩放点积注意力 Bahdanau注意力 多头注意力机制 自注意力和位置编码 transfo
  • (java)leetcode-445 Add Two Numbers II(两数相加 II)

    题目描述 给你两个 非空 链表来代表两个非负整数 数字最高位位于链表开始位置 它们的每个节点只存储一位数字 将这两数相加会返回一个新的链表 你可以假设除了数字 0 之外 这两个数字都不会以零开头 进阶 如果输入链表不能修改该如何处理 换句话
  • jupyter的安装与使用

    目录 一 jupyter的介绍 二 安装与运行 1 使用Anaconda安装 2 使用pip命令安装 1 首先通过win R打开命令符输入pip version 查看电脑python环境 编辑 2 输入jupyter notebook的命令
  • 有时OPEN***提示报错,如下错误及解决方法

    Dec 14 11 40 47 nfs12 open 31685 TLS ERROR BIO read tls read plaintext error error 14090086 SSL routines SSL3 GET SERVER
  • VScode绑定码云并向仓库上传代码

    文章目录 一 下载git 二 使用步骤 1 Git的全局配置 2 配置Git 3 VScode的配置 总结 一 下载git 下载链接 点击download即可 下载完成后 按照默认安装即可 二 使用步骤 1 Git的全局配置 代码如下 示例
  • 卸载Ubuntu自带的Qt4和Qt5

    执行如下操作 首先移除库 sudo apt get remove qtcreator sudo apt get remove qt5 上面是移除qt5 移除qt4的时候把qt5改成qt4就可以了 下面也是一样的 移除依赖文件 sudo ap
  • 《Python进阶系列》一:使用Python包组织代码

    使用Python包 package 组织代码 最近在看 Python入门技能树 时 看到了Python包组织代码觉得很有意思 特地写个笔记总结一下 quad Python 通过包 package 的方式来组织代码 包是一种特殊的模块 mod