Python中的模块系统

简介: Python中的模块系统


模块


随着程序功能越来越复杂,代码量也急剧增加。可以通过将逻辑相近的代码分割到不同的文件中,减少单个文件中代码的行数,提高可维护性。在Python中一个py文件就是一个模块,一个大型的代码项目,一般是由多个文件(模块)组成。一个模块可以被另一个模块导入使用。

在Python中,包含__init__.py文件的目录被称为包,包被用来声明模块之间的查找关系。比如下面的app就是一个包,test也是一个包。app可以被看做是test的子包。

test├──app├──config.py├──__init__.py└──lib.py├──__init__.py└──main.py


__init__.py文件可以为空。__init__.py文件中一般用来导出所在目录下的其他模块。
当目录中不存在__init__.py文件时,该目录也可以被称为一个包,只是习惯上喜欢在每个目录中放置一个__init__.py文件。至于两者区别,含有__init__.py的目录,可以讲__init__.py看做一扇可以通往该目录下所有模块的大门,


导入方法


在Python中导入一个包或模块时,有两种主要的方法,一种是使用import关键字进行导入,另一种是使用官方库importlib来进行导入,后者常被用于一些需要自定义导入的,或者是自动导入某些模块的场景下。


导入一个模块

app├──config.py├──__init__.py└──lib.py


lib.py导入config.py时,可以直接通过import进行导入

# lib.pyimportconfig


导入一个包

test├──app├──config.py├──__init__.py└──lib.py├──__init__.py└──main.py


main.py中导入app包时,可以直接使用import进行导入

# main.pyimportapp


与导入模块不同,导入一个包时,包目录下的__init__.py文件会被自动执行。


导入包中的某一个具体模块时

importapp.lib


那么导入一个包可以认为是通过下面这种方式进行导入的,只是在Python中可以将这种方式简写为imoprt app

importapp.__init__asapp


as


在导入时,Python会将当前导入的包或模块自动添加到全局变量空间中,有时可能会出现下面这种情况

importlib1.appimportlib2.app


在不同的包中,存在名字相同的模块,这是后者就会将前者覆盖,通过as可以将导入的变量重命名。

importlib1.appasapp1importlib2.appasapp2


使用相对路径进行导入


当代码项目过大时,文件关系复杂或者模块的嵌套层级过深时,可以通过相对导入的方式进行导入某一个模块

test├──app├──config.py├──__init__.py├──lib.py└──__pycache__└──__init__.cpython-39.pyc├──auth├──config.py└──__init__.py├──__init__.py└──main.py


app/lib.py文件需要使用auth/config.py模块的功能时,可以这样进行导入

# app/lib.pyfrom ..authimportconfigasauth_config


这种导入方法必须是使用from进行导入,包前面一个点表示同一目录,两个点表示上一级目录,三个点表示上一级目录的上一级目录,以此类推。
在使用这种方法时,对于新手经常会出现下面这种报错

ImportError: attemptedrelativeimportwithnoknownparentpackage


出现这种原因是因为,在使用相对导入时,必须存在一个最上层位置,在Python中,使用python main.py运行main.py文件,则main.py所在的目录即为最上层位置,其他的则为下层位置。当python test/app/lib.py时,最上层位置变成了test/app,所以此时..auth自然无法找到。解决方法是,在使用相对路径导入时,要明确最后运行文件的所在目录,来确定最上层位置,如果你确定不了,那就最好不要使用。


循环导入


当一个项目的模块数量很多时,可能模块之间的依赖关系错综复杂,会出现A导入B,而B也导入了A,从而构成了循环导入的情况。

# A.pyimportBprint(B.b)
a=1# B.pyimportAprint(A.a)
b=1
pythonA.pyAttributeError: partiallyinitializedmodule'B'hasnoattribute'b' (mostlikelyduetoacircularimport)


出现循环引用问题,绝大多数情况都是因为人为设计失误造成的,你可以通过引入新模块,减少A和B相互依赖的变量。


importlib


在使用import关键字导入模块时,会调用内置的__import__方法,通过importlib可以绕过__import__方法,实现自己的导入模块的逻辑,比如在导入前做一些初始化工作,或者是进行自动导入的逻辑。

test├──app├──config.py├──__init__.py├──lib.py└──__pycache__└──__init__.cpython-39.pyc├──auth├──config.py└──__init__.py├──__init__.py└──main.py


fromimportlibimportimport_moduleapp_config=import_module('app.config')


需要注意的是,在使用这种方式在导入一个包下面的模块时,__init__.py也会自动被调用。


一些常见的import写法

fromappimportconfigasapp_configimportapp.configasapp_config# import * 表示导入所有的模块fromappimport*asapp_all


Python是如何进行查找路径的


在Python中,import通过sys.path下面的路径进行查找要导入的包或模块。Python首先会先从当前目录中查找模块,找不到会继续从sys.path下面进行查找,最后找不到会抛出错误。
可以通过修改sys.path来修改查找的顺序,比如下面这样

test├──app├──config.py├──__init__.py├──lib.py└──__pycache__└──__init__.cpython-39.pyc├──auth├──config.py└──__init__.py├──__init__.py└──main.py
# test/app/config.pyapple='apple'# test/main.pyimportsyssys.path.append('./app')
importconfigprint(config.apple)  # apple


资料引用


https://docs.python.org/zh-cn/3/reference/import.html#
https://docs.python.org/zh-cn/3/library/importlib.html#
https://docs.python.org/zh-cn/3/tutorial/modules.html#

相关文章
|
3天前
|
传感器 JSON 监控
python中psutil模块的使用详解(python3经典编程案例)
这篇文章介绍了如何使用Python的`pyinstaller`库打包应用程序,并提供了详细的打包步骤和参数说明。
21 7
|
2天前
|
前端开发 Python
python之【Tkinter模块】
python之【Tkinter模块】
11 5
|
2天前
|
Python
|
3天前
|
安全 Python 容器
Python中好用的模块-collections
文章介绍了Python中collections模块的几个实用组件,包括Counter、defaultdict、OrderedDict、namedtuple、deque和ChainMap的功能与使用方法。
15 2
|
3天前
|
关系型数据库 MySQL Python
pymysql模块,python与MySQL之间的交互
pymysql模块,python与MySQL之间的交互
|
3天前
|
Unix Linux 网络安全
python中连接linux好用的模块paramiko(附带案例)
该文章详细介绍了如何使用Python的Paramiko模块来连接Linux服务器,包括安装配置及通过密码或密钥进行身份验证的示例。
9 1
|
3天前
|
API 语音技术 开发者
用python实现文字转语音的5个较好用的模块
这篇文章介绍了五个Python模块:gtts、pyttsx3、baidu-aip、pywin32和speech,它们能够实现文本到语音的转换功能。
10 1
|
1天前
|
Python
7-14|salt之安装Python模块
7-14|salt之安装Python模块
|
3天前
|
Shell Linux Python
python执行linux系统命令的几种方法(python3经典编程案例)
文章介绍了多种使用Python执行Linux系统命令的方法,包括使用os模块的不同函数以及subprocess模块来调用shell命令并处理其输出。
10 0
|
3天前
|
数据可视化 搜索推荐 JavaScript
pyecharts模块的几个经典案例(python经典编程案例)
文章提供了多个使用pyecharts模块创建数据可视化的Python编程案例,展示如何生成各种类型的图表并进行定制化设置。
9 0