当前位置: 首页 > news >正文

Python模块与包

目录

一、模块(Module)

1. 模块的概念

2. 模块的作用

3. 创建模块

4. 导入模块

5. 模块的 __name__ 属性

6. 模块的 __all__ 变量

二、包(Package)

1. 包的概念

2. 包的作用

3. 创建包

3. 使用包

4. __init__.py 的作用

5. 相对导入

6. 第三方包

三、模块与包的搜索路径

四、模块与包的使用规范


一、模块(Module)

1. 模块的概念

模块是一个包含Python代码的文件,文件扩展名为 .py。模块可以包含类、函数、变量和可执行代码。通过模块,我们可以将代码逻辑划分为独立的单元。

2. 模块的作用

一个模块就是一个工具包,不同的模块能实现不同的功能。

3. 创建模块

只需创建一个 .py 文件,也叫自定义模块,包含可重用的代码(如类、函数、变量等)。例如,创建一个名为 mymodule.py 的文件:

 # mymodule.py
 def greet(name):
     return f"Hello, {name}!"
 ​
 def add(a, b):
     return a + b

4. 导入模块

(1)使用 import 关键字导入整个模块,然后访问其中的函数或变量。

 import mymodule
 ​
 print(mymodule.greet("Tom"))  # 输出: Hello, Tom!
 print(mymodule.add(3, 5))  # 输出: 8

(2)导入模块中的特定函数或变量。

 from mymodule import add
 ​
 print(add(3, 5))  # 输出: 8

(3)导入模块并为其设置别名。

 import mymodule as m
 ​
 print(m.add(3, 5))  # 输出: 8

(4)导入模块中的特定函数或变量,并为其设置别名。

 from mymodule import add as a
 ​
 print(a(3, 5))  # 输出: 8

(5)导入模块中的所有内容。这种方法和 import mymodule 的区别是调用模块里的变量或函数等前面不用加 mymodule. 。但是不推荐使用这种方法,容易造成命名冲突。

 from mymodule import *
 ​
 print(add(3, 5))  # 输出: 8

5. 模块的 __name__ 属性

每个模块都有一个内置的 __name__ 属性。当模块被直接运行时,__name__ 的值为 "__main__";当模块被导入时,__name__ 的值为模块名。

 # mymodule.py
 if __name__ == "__main__":
     print("This module is being run directly!")
 else:
     print("This module is being imported!")

6. 模块的 __all__ 变量

如果一个模块文件中有 all 变量,当在别的文件中使用 from mymodule import * 导入该模块时,只能导入 all 变量中的元素。

  • 定义 __all__

在模块中,将 __all__ 定义为一个列表,列出所有希望公开的名称。

 # mymodule.py
 ​
 __all__ = ['greet']  # 只公开greet
 ​
 def greet(name):
     return f"Hello, {name}!"
 ​
 def private_function():
     return "This is private!"
  • 使用 from module import *

当使用 from module import * 时,只有 __all__ 中列出的内容会被导入。

 from mymodule import *
 ​
 print(greet("Tom"))  # 输出: Hello, Tom!
 ​
 # 以下代码会报错,因为 _private_function 不在 __all__ 中
 print(private_function())

如果要使用 private_function() ,可以再使用 from mymodule import private_function 导入。

二、包(Package)

1. 包的概念

包是一个包含多个模块的目录(文件夹)。包通常还包含一个特殊的文件 __init__.py,用于标识该目录是一个包。

2. 包的作用

包可以将相关的模块组织在一起,形成一个逻辑上的分组,可以帮助我们管理这些模块。通过将模块放在不同的包中,还可以避免模块之间的命名冲突。

3. 创建包

创建一个目录,并在其中放置模块文件和 __init__.py 文件。例如:

 mypackage/
     __init__.py
     module1.py
     module2.py
  • __init__.py 可以是空文件,也可以包含包的初始化代码。

  • 包可以嵌套,形成多层级的包结构。

3. 使用包

使用点号(.)访问包中的模块。例如:

 from mypackage import module1
 import mypackage.module1
 from mypackage.module2 import some_function

4. __init__.py 的作用

  • 标识目录为包。

  • 在导入包时,__init__.py 中的代码会被执行。

  • 通过在 __init__.py 中定义 __all__ 变量,可以控制 from package import * 语句的导入行为,指定哪些模块或子模块可以被导入。例如:假设有一个名为 my_package 的包,其中 module1.pymodule2.py 是两个模块。我们希望在使用 from my_package import * 时,只导入 module1,而不导入 module2。我们可以在 __init__.py 中定义 __all__ 变量如下:

 # my_package/__init__.py
 __all__ = ["module1"]

这样,当执行 from my_package import * 时,只有 module1 会被导入到当前命名空间中,而 module2 不会被导入。

5. 相对导入

在包内部,可以使用相对导入来引用其他模块。例如:

 # mypackage/module2.py
 from .module1 import greet
  • . 表示当前目录。

  • .. 表示上级目录。

6. 第三方包

Python第三方包是Python生态系统中除标准库之外的模块或包,由社区开发者或团队维护和开发。这些包极大地扩展了Python的功能,涵盖了数据分析、科学计算、Web开发、网络编程等多个领域。pip 是Python官方推荐的包管理工具,可以通过命令pip install 包名安装第三方包。

三、模块与包的搜索路径

当导入模块或包时,Python会按照以下顺序搜索:

  1. 当前目录。

  2. 环境变量 PYTHONPATH 指定的目录。

  3. Python标准库目录。

  4. site-packages 目录(第三方库的安装位置)。

可以通过 sys.path 查看搜索路径:

 import sys
 print(sys.path)

如果需要添加自定义路径,可以修改 sys.path

 import sys
 sys.path.append("/path/to/your/module")

四、模块与包的使用规范

  1. 命名规范

    • 模块名使用小写字母和下划线(如 my_module.py)。

    • 包名使用小写字母(如 mypackage)。

  2. 避免循环导入: 模块之间相互导入可能导致循环导入错误,应尽量避免。

  3. 使用 __init__.py 定义包的公共接口: 将常用的函数或类在 __init__.py 中导入,方便用户使用。

  4. 使用 if __name__ == "__main__":: 确保模块的测试代码不会在导入时执行。

  5. 合理组织包结构: 根据功能将模块分组到不同的包中,避免将所有代码放在一个模块中。

相关文章:

  • 一、MySQL8的my.ini文件
  • linux ptrace 图文详解(三) PTRACE_ATTACH 跟踪程序
  • C语言入门教程100讲(8)算术运算符
  • Redis缓存与数据库 数据一致性保障
  • 2:认识数据库
  • 在 .NET 9.0 Web API 中实现 Scalar 接口文档及JWT集成
  • CIFAR10 数据集自定义处理方法
  • Spring Boot 整合 OpenFeign 教程
  • VitePress由 Vite 和 Vue 驱动的静态站点生成器
  • 自然语言处理(5)—— 中文分词
  • 高等数学-第七版-上册 选做记录 习题5-2
  • Linux——线程
  • 构音障碍(Dysarthria)研究全景总结(1996–2024)
  • 在Mac M1/M2芯片上完美安装DeepCTR库:避坑指南与实战验证
  • systemd-networkd 的 /etc/systemd/network/*.network 能不能一个文件配置多块网卡?不能
  • [01-04-02].第20节:PyQt5库初识及实现简易计算器
  • 网络安全基础
  • 文字变央视级语音转换工具
  • OpenRAND可重复的随机数生成库
  • 元宇宙时代下的 Facebook:机遇与挑战
  • 马上评|“衣服越来越难买”,对市场是一个提醒
  • 金砖国家召开经贸联络组司局级特别会议,呼吁共同抵制单边主义和贸易保护主义
  • 地下5300米开辟“人造气路”,我国页岩气井垂深纪录再刷新
  • 浙江公开征集涉企行政执法问题线索,包括乱收费、乱罚款等
  • 技术派|巴基斯坦导弹:让印度保持克制的“定海神针”?
  • 中美经贸高层会谈将在午餐后继续