__init__.py的作用

其实吧,这个问题挺常见的,尤其是对Python新手来说简直就是一团迷雾。今天就站在一位老程序员的角度来给大家唠一唠__init__.py的用途和奥秘,顺便帮大家“踩踩坑”,看看有哪些用法需要注意。

  1. init.py 是个啥?
    init.py,顾名思义,这个文件名就透露出它是用来“初始化”的。在Python里,它主要用于标识一个目录是一个“包(Package)”。
    你在项目里新建了一个文件夹,要让它成为一个可供导入的模块包,最简单的办法就是在里面加一个__init__.py。
    比如,咱们有个项目结构如下:
    my_project/
    ├── init.py
    ├── module1.py
    └── module2.py
    当我们想要在外部使用my_project这个包时,就可以这样导入:
    import my_project
    有了__init__.py的存在,Python才知道my_project是一个包,而不是一个普通的文件夹。
    所以这个文件的基本作用就是:告诉Python,“这里是个包,你可以在其他地方导入我!”
  2. init.py 还能做些啥?
    很多初学者以为这个文件只能“声明”包,实际上它的用法比你想象的要丰富得多。在__init__.py里你可以编写代码,它会在包被导入时自动执行。这有什么用呢?我给大家举几个常见的例子:
    模块初始化操作
    假如你有一个需要初始化配置的工具包,你可以在__init__.py里直接搞定这些初始化工作。
 #例子:my_project/__init__.pyimport os#初始化配置文件路径config_file = os.path.join(os.path.dirname(__file__), 'config.yaml')print("正在初始化配置文件……")

这样,当你一导入my_project时,config.yaml就被自动加载了,是不是很方便?你再也不用在每个子模块里重复配置路径啦!
控制子模块导入
通过在__init__.py中用from .sub_module import some_function的方式,可以直接在import package_name的时候就将所有常用的子模块或者函数导入,这样你就能从包的顶级目录直接访问子模块的内容了:# 例子:my_project/init.pyfrom .module1 import func1from .module2 import func2
#这样你就可以这样用:# import my_project# my_project.func1()
你看,这种做法就好比你开了一个餐厅,顾客刚一进门就能看到招牌菜,这样体验就好了,少了很多绕路时间。
包级别变量和函数的初始化
你还可以在__init__.py里设置一些全局变量,或者定义一些包级别的工具函数。# 例子:my_project/init.pypackage_name = “my_project”
def show_info(): print(f"欢迎使用{package_name}包!🎉")
这样在任何地方,只要你导入了my_project,就能直接调用show_info()了。
3. init.py 的一些“坑”
俗话说得好,“有光的地方就有阴影”。别看__init__.py这么实用,里面也有不少坑,尤其是**循环导入(Circular Import)**的问题,这个坑可是踩一次怀疑人生那种级别的。
什么是循环导入?
假设你有两个模块module1和module2,然后你在module1.py中写了这样一段代码:# module1.pyfrom .module2 import some_function
然后你又在module2.py里这样写:# module2.pyfrom .module1 import another_function
这就会导致Python在导入包的时候出现死循环,结果是两边互相等待对方加载,最终就会报错或者无法正常导入。
如何解决?

一般来说,解决方案有两种:
延迟导入:将导入语句放在函数内部,而不是放在文件头部。# 在 module1.py 中def call_function_from_module2(): from .module2 import some_function some_function()
重构代码结构:把相互依赖的部分提取出来,放到一个公共模块里,这样两个模块就不会直接互相依赖了。
4. init.py 和相对导入的关系
另外,再讲一个可能让人头疼的点——相对导入和绝对导入。很多小伙伴可能会在__init__.py里用相对导入的语法,比如:from .module1 import func1
乍看上去没啥问题,但等到你跑module1.py这个文件时,就会发现——Boom!报错了!因为相对导入的方式要求你必须从顶层包开始导入。而你直接执行module1.py,Python根本不知道它是从哪个包里来的。
解决方案呢?我建议——尽量使用绝对导入,比如这样:from my_project.module1 import func1
这样不管你是直接运行module1.py,还是导入整个my_project,都不会有问题。
5. 还有哪些小技巧?
说了这么多,最后再给大家提几个小技巧,帮你在使用__init__.py时少走弯路:
避免复杂逻辑:不要在__init__.py中写太复杂的业务逻辑。它的职责应该是轻量级的初始化和导入,不然以后维护起来会非常麻烦。
模块导出控制:你可以用__all__来控制从包中导出哪些模块或变量。
这样当你用from my_project import *时,Python只会导入__all__指定的内容。all = [‘module1’, ‘module2’]
合并子模块:你可以在__init__.py中把子模块的功能合并到一个命名空间中,让用户使用起来更方便。
记录导入顺序:如果你的包里有很多子模块,建议记录导入顺序,避免因为导入顺序导致一些诡异的Bug。
总体来说,init.py用得好,它能让整个包管理得井井有条,用得不好,它就会变成你代码里的“绊脚石”。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

中间件有哪些分类?

中间件的分类 中间件是位于操作系统和应用程序之间的软件,它提供了一系列服务来简化分布式系统中的应用程序开发和集成。中间件可以根据其功能和用途被分为不同的类别。以下是中间件的一些主要分类: 1. 通信处理(消息)中间件&am…

利用编程思维做题之反转链表

牛客网题目 1. 理解问题 给到我们的是一个单链表的头节点 pHead,要求反转后,返回新链表的头节点。 首先在心里设想能够快速理解的例子,如给你123序列,要你反转此序列如何回答?将最后一个数字3作为头,然后修…

使用Qt Creator创建项目

个人主页:C忠实粉丝 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C忠实粉丝 原创 使用Qt Creator创建项目 收录于专栏【Qt开发】 本专栏旨在分享学习Qt的一点学习笔记,欢迎大家在评论区交流讨论💌 目录 温馨提示: 1. 新…

基于SpringBoot+Vue的非物质文化遗产保护与传播系统设计实现(地图组件)

🎈系统亮点:地图组件; 一.系统开发工具与环境搭建 1.系统设计开发工具 后端使用Java编程语言的Spring boot框架 项目架构:B/S架构 运行环境:win10/win11、jdk17 前端: 技术:框架Vue.js&#x…

C/C++进阶(一)--内存管理

更多精彩内容..... 🎉❤️播主の主页✨😘 Stark、-CSDN博客 本文所在专栏: 学习专栏C语言_Stark、的博客-CSDN博客 其它专栏: 数据结构与算法_Stark、的博客-CSDN博客 ​​​​​​项目实战C系列_Stark、的博客-CSDN博客 座右铭&a…

RDD优化:缓存和checkpoint机制、数据共享(广播变量、累加器)、RDD的依赖关系、shuffle过程、并行度说明

文章目录 1. 缓存和checkpoint机制1.1 缓存使用1.2 checkpoint1.3 缓存和checkpoint的区别 2. 数据共享2.1 广播变量2.2 累加器 3. RDD依赖关系4.shuffle过程4.1 shuffle介绍4.2 spark计算要尽量避免shuffle 5. 并行度 1. 缓存和checkpoint机制 缓存和checkpoint也叫作rdd的持…

Springboot 整合 Java DL4J 实现企业门禁人脸识别系统

🧑 博主简介:历代文学网(PC端可以访问:https://literature.sinhy.com/#/literature?__c1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,精通Java编程,…

vue后台管理系统从0到1(3)element plus 的三种导入方式

文章目录 vue后台管理系统从0到1(3)element plus 的三种导入方式element plus 引入方式完整引入按需导入手动导入 vue后台管理系统从0到1(3)element plus 的三种导入方式 element plus 引入方式 官方网址:https://el…

windows系统更新升级node指定版本【避坑篇!!!亲测有效】(附带各版本node下载链接)一定看到最后!不用删旧版!

Node.js 是一个开源、跨平台的 JavaScript 运行时环境,广泛应用于服务器端和网络应用的开发。随着 Node.js 版本的不断更新,我们可能需要升级到特定版本以满足项目需求或修复安全漏洞。又或者是学习开发另外一个新项目,新项目对Node版本要求更…

优达学城 Generative AI 课程2:Large Language Models (LLMs) Text Generation

建议先了解一下附录知识。 文章目录 1 官方课程内容自述Lesson 1: 大型语言模型(LLMs)简介Lesson 2: 自然语言处理(NLP)基础Lesson 3: Transformer 和注意力机制Lesson 4: 检索增强生成(RAG)Lesson 5: 为大…

查找企业联系电话的几种方法

在商业合作和销售拓展的过程中,找到企业的联系电话是至关重要的一步。无论是精准营销还是客户开发,拥有有效的联系方式可以大大提高成功率。那么,如何快速有效地查找企业联系电话呢?下面介绍几种常见的方法,以及如何借…

如何解决项目跟进中关键节点难以把控的问题?

在项目跟进的过程中,关键节点的把控常常是一个棘手的问题。如果不能有效地管理这些节点,项目可能会偏离轨道,导致延误、成本超支甚至失败。下面我们来分析一下都有哪些关键节点难以把控以及相应的应对策略。 1、需求变更节点 在项目进行中&a…

快速入门Tomcat服务(业务发布基础技能)

文章目录 1 Tomcat简介 2 安装tomcat 2.1 安装jdk 2.2 安装Tomcat 3 Tomcat目录结构 4 Tomcat重要配置文件 1 Tomcat简介 Tomcat是Sun公司官方推荐的Servlet和JSP容器,在中小型系统和并发访问用户不是很多的场合下,其作为轻量级应用服务…

无刷直流电机工作原理:【图文讲解】

电动机 (俗称马达) 是机械能与电能之间转换装置的通称。可以分为电动机和发电机.一般称电机时就是指电动机。这个在日常应用中,比较多见,比如机器人,手机,电动车等。 直流电机:分为有刷直流电机(BDC&#…

HTTP的工作原理

HTTP(Hypertext Transfer Protocol)是一种用于在计算机网络上传输超文本数据的应用层协议。它是构成万维网的基础之一,被广泛用于万维网上的数据通信。(超文本(Hypertext)是用超链接的方法,将各种不同空间的文字信息组…

【MySQL】CRUD增删改查操作

文章目录 CRUD简介一、Creat 新增1.单行数据全列插入2.单行数据全指定列插入3.多行数据指定列插入 二、Retrieve 检索1.全列查询 --练习阶段最简单的查询:(在生产环境最好不要用!!)2.指定列查询3.结果去重查询4.where条…

柒拾伍- AI内容农场生产文章自动发布至公众号 (一)

一、内容农场 X AI 看过很多的新闻说 AI 产生 内容 污染网络,我也想试一下到底能污染成怎样。 然后为了编写爆款的内容,我选用这个 内容农场 的种子是来源于 微博热搜,让生长出来的垃圾文章更加火爆 涉及内容不能放 二、编写代码 关于代…

常用类(一)----包装类的使用和分析

文章目录 1.包装类2.课堂测试题3.包装类方法4.Integer创建机制5.Integer面试题 1.包装类 概念:基本数据类型对应的类就是包装类,就是为了把基本数据类型转换为包装类,使用这个类里面的方法操作数据----装箱的过程; //装箱&#…

springboot查询全部部门流程

前端发送请求后,会请求DeptController的方法list()。 package com.intelligent_learning_aid_system.controller;import com.intelligent_learning_aid_system.pojo.Dept; import com.intelligent_learning_aid_system.pojo.Result; import com.intelligent_learni…

ArcGis JS天地图 暗色地图

方法一&#xff1a;使用css filter 在body下增加svg&#xff0c;并增加需要用到的滤镜&#xff0c;这边用到x-rays <svg id"svgfilters" aria-hidden"true" style"position: absolute; width: 0; height: 0; overflow: hidden"version"…