欢迎光临
我们一直在努力

12_模块与包

模块概述

Python中一个以.py结尾的源文件即为一个模块(Module)。其中可以包含变量、函数和类等。通常情况下,我们把能够实现某一特定功能的代码放置在一个文件中作为一个模块。

使用模块提高了代码的可维护性,也提高了代码的复用性。即编写好一个模块后,只要是实现该功能的程序,都可以导入这个模块实现。另外,使用模块也可以避免名称冲突,相同名字的函数或变量可以分别存在与不同的模块中。

创建模块

模块名区分大小写,且不能与Python自带的标准模块重名。
创建一个模块my_add.py

num =100
def add(a, b):
"""求两个数的和"""
return a + b

导入模块

全部导入import

导入模块的所有成员,通过模块名.成员名的方式访问。即使多次使用 import导入同一模块,模块也只会被导入一次。

1)语法

import 模块名 [as 别名]

2)案例
在同一目录下创建一个main.py文件,在其中导入 my_add.py 模块并使用。

# 导入模块
import my_add

# 使用模块
print(my_add.add(1, 2))
print(my_add.num)

也可以在导入模块时给模块起别名。

# 导入模块
import my_add as a1

# 使用模块
print(a1.add(1, 2))
print(a1.num)

局部导入 from import

指定导入模块的部分成员,直接通过成员名的方式访问。只能使用其导入的成员,未导入的成员不能使用。如果多个模块中存在重名成员,后一次导入会覆盖前一次导入。

1)语法

from 模块名 import 成员名1[as 别名], 成员名2[as 别名],

2)案例

  • 创建新的模块my_multi.py

num =200
_str1="abc"
def multi(a, b):
"""求两个数的积"""
return a * b

  • 只能使用导入的成员

from my_add import add
print(add(1, 2))
print(num) # NameError: name 'num' is not defined

  • 重名变量,后一次导入会覆盖前一次导入

# 导入模块
from my_add import add,num
from my_multi import num
# 使用模块
print(add(1, 2))
print(num)

  • 通过别名区分不同模块的变量

# 导入模块
from my_add import add,num as a1
from my_multi import num as m1
# 使用模块
print(add(1, 2))
print(a1)
print(m1)

局部导入 from import *

导入模块中所有不以单下划线开头的成员,直接通过成员名的方式访问。
1)语法

from 模块名 import *

2)案例

# 导入模块
from my_add import *

# 使用模块
print(add(1, 2))
print(num)
print(_str1)

模块搜索顺序

当导入一个模块时,会按照以下顺序进行查找:
(1)当前目录。
(2)PYTHONPATH环境变量中的目录。
(3)包含标准 Python 模块以及这些模块所依赖的任何 extension module 的目录。
可以使用以下方式查看模块搜索顺序:

import sys

print(sys.path)

也可以通过 sys.path.append(路径) 向 sys.path 中临时添加路径。

import sys

print(sys.path)
sys.path.append("./..")
print(sys.path)

all

使用from import *导入模块时,可以在被导入的模块中使用 __all__设置哪些内容可以被导入。all 的设置只针对使用 from import * 导入模块时有效。
在my_add.py 中向__all__添加部分元素:

__all__ = ["num","add"] # 内容必须要用引号引起来

num = 100
num1 = 200
_str1="abc"
def add(a, b):
"""求两个数的和"""
return a + b

在main.py中使用 from my_add import *导入模块中的内容。没在 all 中的变量在使用时会报错:

from my_add import *
print(add(1, 2))
print(num)
print(num1) # NameError: name 'num1' is not defined

而使用import my_add全局导入模块后可以正常使用所有元素:

import my_add
print(my_add.add(1, 2))
print(my_add.num)
print(my_add.num1) # NameError: name 'num1' is not defined

name

在 Python 中,name 是一个特殊的内置变量

  • 当一个Python文件被直接运行时,该文件的__name__属性值为"main"。
  • 当一个Python文件作为模块被导入时,__name__属性会被设置为该模块的名称(即文件名,不包含 .py 后缀)。

1)导入模块时测试代码被执行
有时我们会在模块中写一些测试代码,当模块被其他文件导入时这些测试代码会被执行。
在 my_add.py 中写一些测试代码:

"""my_add.py"""
__all__ = ["num","add"]

num = 100
num1 = 200
_str1="abc"
def add(a, b):
"""求两个数的和"""
return a + b

print(add(10,20))
在 main.py 中导入模块,发现 my_add.py 中的测试代码被执行了:
"""main.py"""
import my_add

2)使用 name == “main” 避免测试代码被执行
为了避免模块被导入时测试代码被执行,我们可以在被导入模块中添加对 name 属性的检查:

"""my_add.py"""
__all__ = ["num","add"]

num = 100
num1 = 200
_str1="abc"
def add(a, b):
"""求两个数的和"""
return a + b

print(__name__)
if __name__ == "__main__":
print(add(10,20))

此时再在 main.py 中导入模块,测试代码不会被执行:

"""main.py"""

import my_add

dir()

dir() 是一个内置函数,主要用于列出对象的属性和方法,或者列出当前作用域中定义的名称,并以一个字符串列表的形式返回。

  • 当你将一个模块作为 dir() 的参数时,它会返回该模块中定义的名称列表,包括函数、类、变量等

import math

# 查看math模块下的
print(dir(math))

  • 当你将一个对象作为 dir() 的参数时,它会返回该对象的属性和方法列表。

class MyClass:
def __init__(self):
self.x = 1
self.y = 2

def method1(self):
pass
obj = MyClass()
print(dir(obj))

  • 当你不传递任何参数调用 dir() 时,它会列出当前作用域中定义的名称,包括变量、函数、类等

def my_function():
pass
variable = 10
print(dir())

包概述

包是一种管理 Python 模块命名空间的形式.

通过使用.模块名来构造Python模块命名空间的一种方式。例如,模块名A.B表示名为A的包中名为B的子模块。通常我们将多个有联系的模块放入一个包中。包与文件夹相似,不过该文件夹下必须有一个__init__.py文件。

假设要为统一处理声音文件与声音数据设计一个模块集(包)。声音文件的格式很多(通常以扩展名来识别,例如:.wav,.aiff,.au),因此,为了不同文件格式之间的转换,需要创建和维护一个不断增长的模块集合。为了实现对声音数据的不同处理(例如:混声、添加回声、均衡器功能、创造人工立体声效果),还要编写无穷无尽的模块流。下面这个分级文件树展示了这个包的架构:

sound/ 最高层级的包
__init__.py 初始化 sound 包
formats/ 用于文件格式转换的子包
__init__.py
wavread.py
wavwrite.py
aiffread.py
aiffwrite.py
auread.py
auwrite.py
...
effects/ 用于音效的子包
__init__.py
echo.py
surround.py
reverse.py
...
filters/ 用于过滤器的子包
__init__.py
equalizer.py
vocoder.py
karaoke.py
...

创建包

init.py 可以只是一个空文件,也可以执行包的初始化代码或设置 all 变量。
在PyCharm创建一个graphic文件夹,并在其中创建circle.py、rectangle.py 文件。其中 init.py 文件暂时为空。 circle.py 和 rectangle.py 文件写入代码。
在这里插入图片描述

circle.py:

"""circle.py"""

radius = 10
PI = 3.1415926

def area(radius):
return PI * radius * radius

def perimeter(radius):
return 2 * PI * radius

rectangle.py:

"""rectangle.py"""

rectangle_width = 10
rectangle_height = 10

def area(width, height):
return width * height

def perimeter(width, height):
return 2 * (width + height)

在包外创建一个 main.py 文件。
整体结构如下,其中 graphic 为一个包:
在这里插入图片描述

导入包

全局导入import

从包中导入模块

1)语法

import 包名.模块名 [as 别名]

2)调用方式 :包名.模块名.成员名

import graphic.circle

print(graphic.circle.area(10)) # 314.15926

使用 import 时,除最后一项外都必须是包。最后一项可以是模块或包,但不能是类、函数或变量。

局部导入包下的模块 from import

从包中导入模块

1)语法

from 包名import模块名 [as 别名]

2)调用方式 :模块名.成员名

from graphic import circle

print(circle.area(10)) # 314.15926

局部导入包下模块的成员 from import

从包中模块导入功能

1)语法

from 包名.模块名 import 成员名 [as 别名]

2)调用方式 : 成员名

from graphic.circle import area

print(area(10)) # 314.15926

局部导入 from import * 从包中导入模块

当我们使用 from import * 时,Python并不会查找并导入包的所有子模块,因为这将花费很长的时间,并且可能会产生我们不想要的副作用。

唯一的解决办法是提供包的显式索引。如果包的 init.py 中定义了 all,运行 from import * 时,它就是被导入的模块名列表。

1)语法

from 包名.模块名 import *

2)调用方式 :模块名.功能名
在 init.py 中添加如下内容:

__all__ = ["circle"]
注意:如果不加会无法导包

在 main.py 中使用 from import * 导入模块:

from graphic import *

print(circle.area(10)) # 314.15926
print(rectangle.area(10)) # 报错

常用标准库(包)

标准库指的是在安装Python时就一同被安装的库。这些库经过精心挑选和开发,旨在为Python开发者提供通用且强大的工具集,涵盖各种不同的应用领域。
在这里插入图片描述
在这里插入图片描述

更多标准库可参考https://docs.python.org/zh-cn/3/library/index.html。

引入第三方库

当需要使用Python中没有内置的库时,可以通过以下方式安装第三方库

pip命令方式

pip是Python包管理工具,该工具提供了对 Python 包的查找、下载、安装、卸载的功能。pip 默认的源是 Python Package Index(PyPI),其地址为 https://pypi.org/simple/,如果下载比较慢,还可以指定其它的源

  • 阿里云:http://mirrors.aliyun.com/pypi/simple/
  • 豆瓣:http://pypi.douban.com/simple/
  • 清华大学:https://pypi.tuna.tsinghua.edu.cn/simple/

1)pip常用命令

  • 查看我们已经安装的软件包

pip list

  • 安装软件包-具体包名就什么可以到PyPI上查找

pip install 包名

  • 卸载软件包

pip uninstall 包名

  • 临时使用其他源

pip install i http://mirrors.aliyun.com/pypi/simple/ 包名

  • 永久修改源

pip config set global.indexurl http://mirrors.aliyun.com/pypi/simple/

2)安装requests包步骤
在这里插入图片描述

通过命令行的方式安装,是将第三方包安装在本地python下,例如:D:\\dev\\software\\Python3.12.8\\Lib\\site-packages

Pycharm中引入

1)点击右下角的解释器设置
在这里插入图片描述

2)点击+号
在这里插入图片描述

3)搜索要添加的包
在这里插入图片描述

通过Pycharm安装,我们选择的解释器类型每个项目独立的,所以是将第三方包安装在当前项目环境下,例如:D:\\dev\\workspace\\python-2025.venv\\Lib\\site-packages

打包自己的库并安装

1)先安装 setuptools 库
如果不安装setuptools库,后续打包时可能会遇到报错 ModuleNotFoundError: No module named ‘distutils’,所以可以提前安装 setuptools 库。在命令提示符中执行如下命令:

pip install setuptools

2)在包外创建一个 setup.py 文件
在这里插入图片描述

3)setup.py 中添加如下内容

from distutils.core import setup

setup(
name="graphic", # 需要打包的名字
version="1.0", # 版本
py_modules=["graphic.circle", "graphic.rectangle"], # 需要打包的模块
)

4)在 setup.py 同级目录下进行构建
在这里插入图片描述
在这里插入图片描述

5)也可以生成压缩包

python setup.py sdist

在这里插入图片描述

6)pip命令安装自己打的库

pip install path_to_your_package/dist/your_package_name0.1.tar.gz

在这里插入图片描述

7)Pycharm安装自己打的包库
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

赞(0)
未经允许不得转载:171主机测评 » 12_模块与包
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址