51、Python之模块和包:Python的包和文件夹有何区别

news2024/9/25 11:20:59

引言

大学有云:“苟日新,又日新,日日新”。

看到一些教材或者文章,介绍到包的时候,一定会提到一定要在文件夹中新建一个__init__.py的文件,哪怕空文件也可以……

我只想说,有些人的知识真的是需要更新迭代了。

虽然,据我所知,有些古董级的Python项目代码甚至仍然是基于Python2.x环境的,毕竟有些代码虽然危如屎山,只要还能跑起来,一般人谁敢乱动……

本文的主要内容有:

1、隐藏式命名空间包与传统包

2、责任的转嫁

3、__init__.py文件是否还有必要

命名空间包与传统包

先解释下这两种包的含义:

1、传统包(Regular Package):在Python的早期版本(3.3之前),需要在文件夹中创建一个名为__init__.py的文件,哪怕是空文件,也要创建,因为这是当时识别包的唯一方式。

2、命名空间包(Namespace Package):在Python3.3及更高版本中,Python解释器可以自动识别包,不再需要通过__init__.py文件了。

通过前面两种包的解释,就能清楚地知道,在Python3.3及之后的版本中,创建包的时候,__init__.py是非必须的了。

所以,我们在通常情况下,我们只要用不同的文件夹进行.py文件(模块)的组织,既可以自动创建相应的包(本质上也是模块)对象了。

在PyCharm等IDE中,通过创建文件夹(Directory)或者创建Python包(Python Package),其实都是可以作为Python包的。不同的是,前者就是一个文件夹,作为命名空间包来使用;后者更多的保留传统包的形式,会在创建文件夹的同时,在文件夹下创建一个名为__init__.py空文件。

b2759b5048417220bbcb63bfa2e07a7b.jpeg

5f4aa5ada68a4d7c6045e20ebb5b6791.jpeg

责任的转嫁

之前要创建一个包,即使没有特殊需求,也必须添加一个名为__init__.py的空文件,因为只有这样,Python解释器才能识别到它是包。

其实,从责任界定的角度来看,是很不合理的。

本应该由解释器来承担的责任,被转移给了开发者。

之所以要创建在我们看来完全没有必要的空文件__init__.py,只是因为Python解释器识别、解析包的能力不足,所以开发者必须多做一些不必要的工作。

在信息系统领域,类似的“责任转嫁”的场景,最典型的应该就是大名鼎鼎的“验证码(CAPTCHA)”。

验证码的全称是“Completely Automated Public Turing test to tell Computers and Humans Apart”,也就是这是一种用于区分用户是计算机还是人类的技术。

这种技术的应用场景,更多的在于系统为了提高自身的安全性,防止自动化攻击、恶意注册、暴力破解等。

这种事情从本来看,就是信息系统没有能力来区分一个用户是计算机还是人类,只好让用户自己告诉系统自己是计算机还是人类。

但是从责任界定的角度,信息系统不应该将信息系统自身的防护工作的负担转嫁给用户,而应该尽量通过技术手段自行承担部分工作,以减少对用户体验的影响。

虽然,后续发展中,验证码技术,甚至被应用与图片标注、文字识别等工作的众包分包形式中,也产生了相对积极的作用。但是,从其出发点来看,显然是不合理的责任转嫁。

而习惯于这种责任转嫁,将不合理视为理所当然,自然是限制进步与创新的阻碍,不小心又扯远了……

__init__.py文件是否还有必要

既然已经有了命名空间包,这种新的识别、解析包的方式,__init__.py是否就彻底沦为时代更迭的残余,理应被彻底淘汰?答案显然是否定的。

前面的描述中,一直有这样一个语境的限定,“在没有特殊需求的情况下”。

在有特殊需求的场景中,是指当__init__.py文件不再是包被识别、解析的标识,由空文件变为非空文件时,该文件所能发挥的作用。

由于在导入包的时候,如果有__init__.py文件,这个文件一定会被优先执行。所以,在有需要的情况下,我们还是可以利用包中的__init__.py文件来做不少事情。

首先简单介绍一下__init__.py文件的相关内容:

1、__init__.py文件,在包被导入时,会自动运行。

2、类似于模块中的__all__可以控制模块被通过from 模块名 import *时的行为,包中的__init__.py文件中,也可以通过__all__控制这种*式导入的行为。

接下来,在包、模块导入的简化及公共模块导入的场景,来看下__init__.py文件能够发挥的作用。

首先看这样一个项目结构:

547c2cbc00ad7378dd62d85ed160e34a.jpeg

其中,pkg1/common.py中定义了一个公共函数:

def com_func():
    print('这是一个公共的函数')

pkg1/m1.py和pkg1/m2.py,定义了两个模块,这两个模块都要调用common.py模块中的com_func()函数。

m1.py文件:

from .common import com_func


def m1_func():
    print("m1_func start")
    com_func()
    print("m1_func end")

m2.py文件:

from .common import com_func


def m2_func():
    print("m2_func start")
    com_func()
    print("m2_func end")

main.py文件,为项目的入口文件:

from pkg1.m1 import m1_func
from pkg1.m2 import m2_func

if __name__ == '__main__':
    m1_func()
    m2_func()

程序的执行结果:

1f967dd836ae750cadf2be28985e91bc.jpeg

其中,存在一些重复的、或者相对繁琐的导入工作,比如m1和m2都要导入common.py中的功能,如果公共模块的功能比较多,或者有多个公共模块,或者多个模块要调用多个公共模块,则会有很多行重复的模块导入的代码。

在入口文件中,如果模块较多,则要写多行,如果包下又有自保,模块导入的路径也会过于冗长。

接下来,利用__init__.py文件对代码进行优化:

首先,项目结构这是在包pkg1下新增了一个__init__.py文件:

b96e67fb029f4043008cbe2a0333527e.jpeg

其中,__init__.py文件内容为:

__all__ = ['m1_func', 'm2_func']

from .common import com_func
from .m1 import m1_func
from .m2 import m2_func

m1.py文件:

from . import com_func


def m1_func():
    print("m1_func start")
    com_func()
    print("m1_func end")

m2.py的调整同m1.py

入口文件main.py的调整:

from pkg1 import *

if __name__ == '__main__':
    m1_func()
    m2_func()

执行结果,跟调整前完全一样,只是导入代码进行了简化。

当然,由于__init__.py的运行机制,我们也除了把包中的模块的功能暴露到包级别,还可以作为包的入口文件,进行一些统一的初始化配置等功能,这里就不再展开了。

总结

本文简单介绍了Python中的两种包:命名空间包和传统包,展开论述了关于责任转嫁的问题,最后介绍了__init__.py文件在命名空间包存在的情况下,仍然能发挥的作用。

感谢您的拨冗阅读!

b8ca805a27b401c45fca38304d064e50.jpeg

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2077776.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

等保测评与企业风险管理:构建坚实的信息安全防线

随着信息技术的飞速发展,企业在数字化转型的道路上高歌猛进。然而,随之而来的信息安全威胁也日益严峻,成为制约企业发展的关键因素。为了确保信息系统安全,等保测评作为一种重要的风险管理手段,正逐渐成为企业构建信息…

Automatic Educational Question Generation with Difficulty Level Controls

文章目录 题目摘要简介相关工作问题表述实验用户研究结论 题目 具有难度级别控制的自动教育问题生成 论文地址:https://link.springer.com/chapter/10.1007/978-3-031-36272-9_39 摘要 我们考虑自动生成各种难度的数学应用题 (MWP),以满足教师在相应教育阶段教学和…

Java 使用 POI 导出Excel,实现单元格内容为下拉选项

在使用Apache POI的库生成Excel导入模板的时候,有时候需要设置某些列只能选择下拉选项中的内容,该如何实现这个特性呢?下面是一个示例代码,演示如何实现单元格只能从下拉中选择内容。 代码 import org.apache.poi.ss.usermodel.*…

使用Vue创建cesium项目模版该如何选择?

目录 问题描述模版说明及选用建议小结 问题描述 刚入手这个项目,什么都是一知半解。使用Vue,创建Cesium项目的时候,提示需要选择一个模版(如下图所示),该如何选择项目模版选,总结如下: 模版说明…

共源级PMOS反向串联电路分析

一、共源级PMOS反向串联结构如下图: 二、具体分析 1、当VBUS_EN拉低,三极管Q5截止: 如果V-BUS>GEN_5V, T3体二极管阴极电压大于阳极电压,T3体二极管截止。由于上拉电阻R24将S端电压向G端极间电容充电,使得VgVs&…

【机器学习】探秘图像处理与分类:运用C++结合OpenCV实现智能视觉识别技术

🎬 鸽芷咕:个人主页 🔥 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活! 引言 在计算机视觉领域,图像处理与分类是核心任务之一。OpenCV作为一个功能强大的开源计算机视觉库,提供…

【搜索引擎】ElasticSearch 7.x版本

1 Elasticsearch概述 1.1 Elasticsearch是什么 1.2 全文搜索引擎 1.3 Elasticsearch And Solr 1.4 Elasticsearch Or Solr 1.5 Elasticsearch应用案例 2 Elassticsearch入门 2.1 Elasticsearch 安装 2.1.1 下载软件 2.1.2 安装软件 2.1.3 问题解决 2.2 Elasticsearch基本操…

【网络基础】DNS协议详解:从背景到解析过程及`dig`工具的使用

文章目录 DNS 协议① 前言 - 背景② 域名③ DNS解析过程④ Linux下用dig工具 分析DNS过程⑤ 浏览器中输入URL后,会有哪些过程 DNS 协议 DNS(域名系统,Domain Name System)是互联网的一个核心协议,用于将域名转换为 IP…

有一种“穷人性格”,大事拎不清,小事算太精

在生活的舞台上,人们各自演绎着不同的人生故事。而有一种性格特征,常常被视为与经济困境紧密相连,那就是“大事拎不清,小事算太精”的所谓“穷人性格”。这种性格不仅在个体层面影响着人们的生活轨迹,也在一定程度上反映了社会现象背后的深层次问题。 一、“穷人性格”的表…

读软件开发安全之道:概念、设计与实施10安全设计审查

1. 安全设计审查 1.1. Security Design Review,SDR 1.2. 将安全性融入软件设计的最佳方法之一是戴上“安全帽”进行单独的设计审查 1.3. 安全审查员是熟悉软件运行的系统和环境,以及知道如何使用它的人,但他们不参与设计工作,这…

【SpringCloud】(一文通) 统一服务入口-Gateway

目 录 一. 网关介绍1.1 问题1.2 什么是 API 网关1.3 常见网关实现 二. Spring Cloud Gateway2.1 快速上手2.1.1 创建网关项目2.1.2 引入网关依赖2.1.3 编写启动类2.1.4 添加Gateway的路由配置2.1.5 测试 2.2 Route Predicate Factories2.2.1 Predicate2.2.2 Route Predicate Fa…

<数据集>脑肿瘤识别数据集<目标检测>

数据集格式:VOCYOLO格式 图片数量:5249张 标注数量(xml文件个数):5249 标注数量(txt文件个数):5249 标注类别数:4 标注类别名称:[Glioma, Meningioma, No Tumor, Pituitary] 序号类别名称图片数框数1…

【RabbitMQ】概述

目 录 一. RabbitMQ 概述什么是 MQMQ的作用为什么选择 RabbitMQRabbitMQ 介绍 一. RabbitMQ 概述 前言 Rabbit, 兔子的意思 互联网行业很多公司, 都喜欢用动物命名产品, 或者作为公司的logo, 吉祥物. 比如: 腾讯的企鹅, 京东的狗, 美团的袋鼠, 携程的海豚,阿里就更多了, 蚂蚁…

原生JS实现下滑到当前模块时左右滑动到位

效果图&#xff1a; ​​​​​​​ 源码&#xff1a; <div style"height: 1500px;"></div><div class"software-box"><div class"software-container" style"display: flex;"><div class"software-…

MapBox Android版开发 2 本地化

MapBox Android版开发 2 本地化 前言MapBox V9 本地化示例1示例2示例3运行效果图 MapBox V11 本地化示例运行效果图 前言 前文介绍了MapBox V9和 V11 两个版本配置和显示地图。默认MapBox地图语言为英文&#xff0c;本文重点介绍如何将地图语言设置为中文。 MapBox V9 本地化…

52 mysql 启动过程中常见的相关报错信息

前言 我们这里主要是看一下 service mysql start, service mysql stop 的过程中的一些常见的错误问题 这些 也是之前经常碰到, 但是 每次都是 去搜索, 尝试 1, 2, 3, 4 去解决问题 但是 从来未曾思考过 这个问题到底是 怎么造成的 The server quit without updating PID fil…

【Test 001】Qt 开发基础体系 QMap 类和 QHash 类以及 QVector 类

文章目录 1.QMap 详解1.1 QMap 的介绍1.2 QMap 的具体用法如下1.3 QmultiMap类 2.QHash 详解3. QMap 和 QHash 的对比4. QVector 详解 1.QMap 详解 1.1 QMap 的介绍 &#x1f427;① QMap<key,T>提供一个从类型为Key的键到类型为T的值的映射。通常&#xff0c;QMap存储的…

sheng的学习笔记-AI-半监督SVM

AI目录&#xff1a;sheng的学习笔记-AI目录-CSDN博客 svm: sheng的学习笔记-AI-支持向量机&#xff08;SVM&#xff09;-CSDN博客 半监督学习&#xff1a; sheng的学习笔记-AI-半监督学习-CSDN博客 什么是半监督svm 半监督支持向量机&#xff08;Semi-Supervised Support Ve…

重邮计算机网络803-(3)数据链路层

目录 一.数据链路两种类型 二.使用点对点信道的数据链路层 1. 数据链路和帧 2.数据链路层传送的是帧 三.三个基本问题 1.封装成帧 2.透明传输 ①字节填充法 ②其他方法&#xff1a;字符计数法&#xff0c;比特填充法&#xff0c;违规编码 3. 差错检测 &#xff08;1…

容器存储接口--CSI

文章目录 一、背景二、CSI 是什么三、CSI 系统架构1、CSI 如何与 k8s 组件相互通信2、CSI 由哪些组件组成3、CSI 的工作原理4、k8s 存储中涉及的组件及其作用4.1、Sidecar Containers4.1.1、[external-attacher](https://kubernetes-csi.github.io/docs/external-attacher.html…