PATHON 中的package & modules

本文深入探讨Python中的包和模块概念,讲解其定义、复用方法及代码管理优势。覆盖import与from...import语法,相对与绝对引入的区别,以及如何通过__all__属性批量导入模块。同时,介绍自定义包的本地与网络发布流程,包括setup.py的配置与使用,以及第三方模块的安装与卸载技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. package & modules

在进行python编程时,往往编写大量的代码,一个文件下有过多的代码,一旦要修改或者查找,工作量比较大,不利于其他人的阅读。为了更好的对python进行代码管理,引入的包和模块的概念,将代码按照不同的功能进行整理,来提高代码的可读性和代码质量。

1.1 包和模块的定义

python 中的包和模块,首先是按照代码的功能进行整理,将相似的功能的代码/大量代码整理到一起方便管理。
  • 模块:python中的一个源代码文件就是一个模块,模块名就是文件名称,每个模块中都有封装的变量/函数/类型,可以被其他的python模块通过 import  关键字引用重复使用。
  • 包:python 中的文件夹就是一个包,标准的 python 包是一个文件夹,并且文件夹中有一个包声明文件__init__.py,包声明文件就代表包本身,可以将大量功能相关的 python 模块包含起来统一管理,同样也可以用 import 关键字引入重复使用。

1.2 包和模块的复用

python 中,将代码封装成包和模块,最主要的目的是提高代码的复用性,可以被其他模块引入使用

1.2.1 import 和 from . . import

包和模块引入,通常有两个关键语法:

  • import  包 / 模块
  • from 包 / 模块  import  具体对象

(1)import 方式

import 引入包和模块会自动从site-packages中,系统环境变量 PYTHONPATH 中,以及系统的sys.path 路径中查询是否存在该名称的包和模块

# 直接引入模块
import utils

# 使用过程中,必须通过 模块名称.变量名称/模块名称.函数名称/模块名称.类型名称 使用
# 使用模块中的变量
print(utils.msg)
# 使用模块中的函数
utils.test()
# 使用模块中的类型
p = utils.Person()
print(p)

(2)from . . import 方式

from . import xxx  # 从当前模块路径下,引入xxx模块

from . . import xxx  # 从当前模块的父级路径下,引入xxx模块【】

from pkg import module  # 从pkg 包中引入一个模块 module  【推荐***】

from pkg import msg , test,   # 从指定的模块中直接引入变量/函数/类型

备注1:from . . import 方式主要是针对包结构而特定的代码引入方式,首先要非常明确代码的组织结构才能正确使用from import 语法进行代码的引入和复用 

通过上述代码,可以看到 form import 语法区分为两种操作
  1. 使用了./..相对路径的引入操作方式
  2. 直接使用包/模块名称绝对引入操作方式

1.2.2 模块的引入

1.2.2.1 模块的相对引入

相对引入本身是相对于当前正在操作的文件的路径

  • 同一级路径使用符号:.

  • 上一级路径使用符号:..
#相对引入:从当前文件夹/目录/路径中,查询并引入utils模块
from . import utils

# 使用模块的变量
print(utils.msg)
# 调用执行函数
utils.test()
# 使用模块中的类型
p = utils.Person()
print(p)

1.2.2.2模块的绝对引入

绝对引入操作方式比较直接,从最外层的源头直接开始操作;

# 绝对引入
import utils

# 使用另外一个模块中的变量 (没有全局/局部变量的概念)
print(utils.msg)

# 使用另外一个模块的函数
utils.test()

# 使用另一个模块的类型
p = utils.Person()
print(p)

模块的相对引入和绝对引入的使用情况:

1. 如果开发应用软件/内部项目:产品
    第一种引入方式使用较多,import 模块名称
    ~多人协同开发,当前模块只会在当前项目中使用。

2. 如果开发的工具软件:工具模块~pymysql/pygame
    第二种引入方式使用较多,from pygame import K_A
    ~当前开发的包,可能会被不同的项目引入使用。

1.2.2.2模块的不同引入

# 1. 引入方式:直接一个模块[店家推荐]
import utils

# 使用过程中,必须通过 模块名称.变量名称/函数名称/类型名称 使用
print(utils.msg)
utils.test()
p = utils.Person()


# 2. 引入方式:通过模块,引入模块中的变量/函数/类型
from utils import msg, test, Person # 不推荐:代码的可读性较低

# n行代码

# 分辨不清msg/test/Person 是当前模块的数据,还是其他模块的数据
print(msg)
test()
p = Person()

1.2.3 包的引入

1.2.3.1 包的相对引入与绝对引入

# 1. 绝对引入:直接引入包中的模块
# pycharm开发工具:会自动搜索site-packages/PYTHONPATH/sys.path路径下查询对应的模块
# python解释器(CPython):自动搜索[三个标准路径+当前路径]
import modules.tools
# # 使用模块中的变量
print(modules.tools.msg)
# # 使用模块中的函数
modules.tools.test()
# # 使用模块中的类型
a = modules.tools.Author()
print(a)

# 2. 相对引入方式:包含了相对路径的操作
from .modules import tools
#使用模块中的变量
print(tools.msg)
# 使用模块中的函数
tools.test()
# 使用模块中的类型
author = tools.Author()
print(author)

包的相对引入和绝对引入

  1. 相对于当前正在开发的内部项目,使用相对路径引入包进行操作
        from .modules import tools

2. 相对于要发布到网络上的工具模块/在公司多个项目中使用的公共模块,使用绝对路径引入包的方式进行操作
        from modules import tools

1.2.3.2 包的引入操作

# 1. 直接引入包: 使用包中的模块~必须在当前包的__init__.py文件中主动引入【不推荐】
# import modules

print(modules.tools.msg)
print(modules.utils.msg)
modules.tools.test()

# 2. 直接引入包->模块【推荐:代码可读性较高】
import modules.tools #可以这样引入
print(modules.tools.msg)

import modules.tools as t # 【店家推荐:**】
print(t.msg)

# 熟练
from modules import tools # 【店家推荐:***】
print(tools.msg)

# 3. 包的引入第三种方式【不推荐】
from modules.tools import msg, test, Author

# 原因:可读性很差[变量的定义造成了误读:分辨不清这个变量是当前模块还是其他模块]
print(msg)

msg = "hello"

print(msg)

1.3 模块和包

1.3.1 模块

一个标准模块的定义方式:

# 引入系统标准模块

# 引入第三方模块

# 引入自定义开发模块

# 声明定义变量


# 声明定义函数


# 声明定义类型

1.3.2 包:__all__

默认情况下,包中所有的模块都是可以直接导入的,同样为了使用方便,可以通过通配符的方式来一次引入包中所有指定的模块
__all__属性就是用于模糊导入的特殊魔法属性,值是一个包含模块名称的列表,主要声明在__init__.py 文件中,用于定义可以用通配符的方式引入的模块。

​# modules/__init__.py

__all__ = ['module', 'manager', 'menus']

此时可以在main.py中通过通配符的方式将__all__中包含的模块一次性导入

from users import *

#相当于
from users imoprt module, manager, menus

1.3.3 安装和卸载第三方模块

  • 安装第三方模块的两种方法:

a)pip install <module_name>

b)  下载<module_name>压缩包-> 解压-> python setup.py install

pip list 查看当前解释器中安装的所有第三方模块

  • 卸载第三方模块的方法:

pip uninstall <module_name>

通过 pip uninstall <module_name> 卸载一个模块,一般情况下通过pip install <module_name>安装能卸载成功。但是通过python setup.py install 这样安装的模块有可能卸载失败,需手工进入site-packsge/文件夹中,直接删除要卸载模块对应的文件夹。

1.4. 自定义包的发布

1.4.1. 本地发布

在我们已经开发好的一个包文件夹下,创建一个 python 模块: setup.py
模块中定义如下内容

# 引入构建包信息的模块
from distutils.core import setup

# 定义发布的包文件的信息
setup(
    name="py1808tools",   # 发布包的名称
    version="1.00.001",   # 发布的包的版本序号
    description="我的测试包",   # 发布包的描述信息
    author="小羊咩咩",          # 发布包的作者信息
    author_email="2674635186@qq.com",   # 作者联系邮箱信息
    py_modules=['__init__', 'download', 'engine', 'modules', 'pipelines', 'setup', 'tools', 'utils']   # 发布的包中的模块文件 列表
)

使用MANIFEST.in打包非py的静态资源

具体格式和参数参考https://docs.python.org/2/distutils/sourcedist.html

include HISTORY.rst
include MANIFEST.in
recursive-include image *.png
recursive-include music *
recursive-include plane/font *.ttf
recursive-include plane/image *
recursive-include plane/image1 *
recursive-include plane/sound *.mp3 *.ogg *.wav

执行当前程序包文件的构建操作命令:按照标准格式组织包中的所有数据文件

python setup.py build
REMARK:构建完毕的文件
可以通过 python setup.py install 命令直接当成第三方模块进行安装

执行命令进行包的打包发布

python setup.py sdist
REMARK:打包的文件,主要是方便进行网络传输,打包之后会在 dist 中创建包含包中所有信息的 tar.gz 压缩包文件;

1.4.2. 网络发布

首先,进入 http://pypi.org 网站上,注册一个自己的账号吧!

其次:你已经准备好打包好的 python 程序包,并在包中准备好了 setup.py 文件

接下来:将是激动人心的时刻!
首先安装第三方模块:twine,用于上传我们打包的项目文件
pip install twine

上传项目
twine upload dist/*

1.5. 关于 Main 主方法
对比其他语言,其他语言都有一个特殊的程序入口,main方法/main函数

python 中最小的执行单元:代码块~不存在main方法/函数

为了程序的完善性~模拟了一个main方法的操作

python文件 -> python模块->模块名称__name__

默认情况下,模块的名称__name__就是文件的名称,如果当前python 文件是执行文件【python xxx.py】

————> __name__ ="__main__"

每个python模块都有一个魔法属性 __name__,指代当前模块的名称

为了保证被引入模块的测试代码不至于在import时执行导致错误,一般情况下,每个模块中的测试执行代码,都需要包含在一个选择判断中【main函数/方法】

if __name__ == "__main__":

当前模块作为运行模块 要执行的代码

  1. 测试代码
  2. 程序入口

面试题:能简单说说Python 中的main函数/方法

  • python 中没有所谓的main函数/方法
  • python 中为了保证测试代码的正确性和程序入口的唯一性,通过选择结构模拟一个main函数/方法,主要通过python模块的魔法属性__name__ 也就是当前模块的名称属性进行操作,默认情况下名称属性就是当前文件模块的名称,但是如果作为模块的话该名称属性的值就会是__main__,所以通过__name__是否是__main__的判断完成了main函数的模拟。
  • 扩展加分:一般情况下我们在开发时,这个模拟main函数/方法中,会有两个作用,第一个作用用来编写测试代码;第二个作用用来规范程序入口。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值