0

0

学习Python模块导入机制与大型项目的规范

coldplay.xixi

coldplay.xixi

发布时间:2020-09-27 17:38:16

|

3113人浏览过

|

来源于juejin

转载

python视频教程栏目今天为大家介绍学习python模块导入机制与大型项目的规范。

学习Python模块导入机制与大型项目的规范

前言

在我们平常工程里使用Python的过程中,经常需要解决各个模块的导入问题,而且也常常遇到引用路径查找不到、交叉导入模块等等问题,故写这篇文章,旨在讲述Python的模块导入机制和我们平时大型项目中应该遵循的模块导入规范

Python模块导入

日常编程中,为了能够复用写过的代码逻辑,我们都会把这些代码封装成为模块,需要用到的时候可以直接导入复用,以便提高我们的开发效率。 module能定义函数、类、变量,也能包含可执行的代码。module来源有3种: ①Python内置的模块(标准库); ②第三方模块; ③自定义模块;

导入原理

模块的导入一般是在文件头使用import关键字,import一个模块相当于先执行了一次这个被导入模块,然后在本命名空间建立一个与被导入模块命名空间的联系,相当于在本命名空间新建了一个变量,这个变量名称是被导入模块的名称,指向被导入模块的命名空间。所以导入的这个模块相当于一个变量,因此多次导入同一个模块只有第一次导入的时候会被执行(后续导入会判断到这个模块变量已存在所以不执行)

997346e5c5df4251ab8633d317077cc5_tplv-k3u1fbpfcp-zoom-1.png

路径查找机制

每一个导入的模块都会在Python内置字典sys.modules中,Python一启动,它将被加载在内存中,当我们导入新modules,sys.modules将自动记录下该module。 Python的模块查找路径的机制是:

  1. 查找sys.path中的所有路径下是否有该模块,有则开辟新空间加载该模块;
  2. 查看sys.modules中是否有内置包或已安装的第三方包,有则开辟新空间加载该模块;

所以对于我们自己编写的模块,如果封装并发布到了PyPi,则可以用pip install直接安装,并在启动时加载在内存中,通过sys.modules可以查看到 而对于仅需要在本项目中复用的模块,我们在复用代码中将其路径加入到sys.path中,同样可以引用到该模块。

绝对路径导入

所有的模块import都从“根节点”开始。根节点的位置由sys.path中的路径决定,项目的根目录一般自动在sys.path中。如果希望程序能处处执行,需手动修改sys.path

立即学习Python免费学习笔记(深入)”;

import sys,os
BASE_DIR = os.path.dirname(os.path.abspath(__file__))#项目根目录所在的绝对路径sys.path.append(BASE_DIR)import A, B #导入A、B包复制代码

相对路径导入

只关心相对自己当前目录的模块位置就好。不能在包(package)的内部直接执行(会报错)。不管根节点在哪儿,包内的模块相对位置都是正确的。

#from . import b2 #这种导入方式会报错,只有在包内部直接执行的时候才可以这样导入。import b2#正确b2.print_b2()复制代码

Python模块导入常见问题

  • 单独import某个包名称时,不会导入该包中所包含的所有子模块 解决办法:导入的包中也包含了其他包的导入,此时需要在每个包的init.py文件中导入该包下的所有模块,最上层才可以直接引用最下层的包的类和方法

init文件

当一个文件夹下有init.py时,意为该文件夹是一个包(package),其下的多个模块(module)构成一个整体,而这些模块(module)都可通过同一个包(package)导入其他代码中。 其中init.py文件 用于组织包(package),方便管理各个模块之间的引用、控制着包的导入行为。

该文件可以什么内容都不写,即为空文件(为空时,仅仅用import [该包]形式 是什么也做不了的),存在即可,相当于一个标记。

在python3中,即使包下没有init.py文件,import 包仍然不会报错,而在python2中,包下一定要有该文件,否则import 包会报错

谱乐AI
谱乐AI

谱乐AI,集成 Suno、Udio 等顶尖AI音乐模型的一站式AI音乐生成平台。

下载

all变量

all 是一个重要的变量,用来指定此包(package)被import *时,哪些模块(module)会被import进【当前作用域中】。不在all列表中的模块不会被其他程序引用。可以重写all,如 all= [‘当前所属包模块1名字’, ‘模块1名字’],如果写了这个,则会按列表中的模块名进行导入

name变量

在包内部直接运行时,包的name == 'main',但是在外部导入包是,可以通过

if __name__ == '__main__':复制代码

来避免实现包内部调试时的逻辑

循环导入

当两个模块A和B之间相互import时,就会出现循环导入的问题,此时程序运行会报错:can not import name xxx,如:

# a.pyprint('from a.py')from b import x

y = 'a'复制代码
# b.pyprint('from b.py')from a import y

x = 'b'复制代码

我们来分析一下这种错误是怎么出现的:

  1. 在sys.modules中查找 符号“module b”;
  2. 如果符号“module b”存在,则获得符号“module b”对应的module对象; 从的dict中获得 符号“x”对应的对象。如果“x”不存在,则抛出异常“ImportError: cannot import name ‘x’”
  3. 如果符号“module b”不存在,则创建一个新的 module对象。不过此时该新module对象的dict为空。然后执行module b.py文件中的语句,填充的dict

因此在a.py中执行from b import x的顺序就是1->3,先引入b,b里面from a import y由相当于执行了a.py,顺序是1->2,因为此时b已经引入所以不会执行3,2中无法找到x对象,因为引入b时还没执行到x='b'这一步,所以报错了

解决办法

  1. 延迟导入,把import语句写在方法/函数里,将它的作用域限制在局部;
  2. 顶层先引入模块,再把from x import y改成import x.y形式;
  3. 其实出现循环引用问题的根本原因是程序设计不合理,每个包都应该由上层使用的模块去导入,而不应该在包与包之间各种相互导入,所以应该更改代码布局,可合并或分离竞争资源;

大型项目中Python模块导入规范

分离模块,将同一类别的模块放在同一目录下,形成类别分明的目录架构,如:

0019951058714d4fb329ac2c37e7905d_tplv-k3u1fbpfcp-zoom-1.png

  1. 每一个模块目录都要写init.py文件,可以同时定义all限定可导入的范围;
  2. 源码根目录可以定义BASE_DIR,限定好根目录路径,启动py文件可以用绝对路径导入各个模块,将必要模块都加入到sys.path中;
  3. 各个服务之间(例如model需要引入common的模块方法),可以通过相对路径引用模块;
  4. 程序设计时避免循环导入,可由调用者(服务文件)作为上层第三方引入需要的各个模块,这样就可以减少各个模块的相互导入。
更多相关免费学习推荐:python视频教程

相关文章

python速学教程(入门到精通)
python速学教程(入门到精通)

python怎么学习?python怎么入门?python在哪学?python怎么学才快?不用担心,这里为大家提供了python速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
Java 桌面应用开发(JavaFX 实战)
Java 桌面应用开发(JavaFX 实战)

本专题系统讲解 Java 在桌面应用开发领域的实战应用,重点围绕 JavaFX 框架,涵盖界面布局、控件使用、事件处理、FXML、样式美化(CSS)、多线程与UI响应优化,以及桌面应用的打包与发布。通过完整示例项目,帮助学习者掌握 使用 Java 构建现代化、跨平台桌面应用程序的核心能力。

37

2026.01.14

php与html混编教程大全
php与html混编教程大全

本专题整合了php和html混编相关教程,阅读专题下面的文章了解更多详细内容。

19

2026.01.13

PHP 高性能
PHP 高性能

本专题整合了PHP高性能相关教程大全,阅读专题下面的文章了解更多详细内容。

37

2026.01.13

MySQL数据库报错常见问题及解决方法大全
MySQL数据库报错常见问题及解决方法大全

本专题整合了MySQL数据库报错常见问题及解决方法,阅读专题下面的文章了解更多详细内容。

19

2026.01.13

PHP 文件上传
PHP 文件上传

本专题整合了PHP实现文件上传相关教程,阅读专题下面的文章了解更多详细内容。

16

2026.01.13

PHP缓存策略教程大全
PHP缓存策略教程大全

本专题整合了PHP缓存相关教程,阅读专题下面的文章了解更多详细内容。

6

2026.01.13

jQuery 正则表达式相关教程
jQuery 正则表达式相关教程

本专题整合了jQuery正则表达式相关教程大全,阅读专题下面的文章了解更多详细内容。

3

2026.01.13

交互式图表和动态图表教程汇总
交互式图表和动态图表教程汇总

本专题整合了交互式图表和动态图表的相关内容,阅读专题下面的文章了解更多详细内容。

45

2026.01.13

nginx配置文件详细教程
nginx配置文件详细教程

本专题整合了nginx配置文件相关教程详细汇总,阅读专题下面的文章了解更多详细内容。

9

2026.01.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 0.6万人学习

Django 教程
Django 教程

共28课时 | 3.1万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号