main
文件信息
- 📄 原文件:
main.py - 🔤 语言:python
Python 模块与包 本文件介绍 Python 中的模块和包的概念与使用。
模块(Module):一个 .py 文件就是一个模块 包(Package):包含 init.py 的目录
完整代码
python
import sys
import os
# 将当前目录添加到路径(用于演示导入本地包)
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
def main01_import_basics():
"""
============================================================
1. 导入基础
============================================================
"""
print("=" * 60)
print("1. 导入基础")
print("=" * 60)
# 【import 语句】
import math
print(f"import math: math.pi = {math.pi}")
# 【from ... import ...】
from math import sqrt, pow
print(f"from math import sqrt: sqrt(16) = {sqrt(16)}")
# 【别名 as】
import math as m
from math import factorial as fact
print(f"import math as m: m.e = {m.e}")
print(f"factorial as fact: fact(5) = {fact(5)}")
# 【导入所有(不推荐)】
# from math import * # 会污染命名空间
# 【导入检查】
print(f"\n--- 导入检查 ---")
print(f"math 模块路径: {math.__file__}")
print(f"math 模块名: {math.__name__}")
def main02_module_search():
"""
============================================================
2. 模块搜索路径
============================================================
"""
print("\n" + "=" * 60)
print("2. 模块搜索路径")
print("=" * 60)
# 【sys.path】模块搜索路径列表
print("模块搜索路径 (sys.path):")
for i, path in enumerate(sys.path[:5]):
print(f" {i}: {path}")
print(" ...")
# 【搜索顺序】
print(f"\n搜索顺序:")
print(" 1. 当前目录")
print(" 2. PYTHONPATH 环境变量")
print(" 3. 标准库目录")
print(" 4. site-packages(第三方包)")
# 【动态添加路径】
# sys.path.append('/custom/path')
# sys.path.insert(0, '/priority/path')
def main03_package_structure():
"""
============================================================
3. 包结构
============================================================
"""
print("\n" + "=" * 60)
print("3. 包结构")
print("=" * 60)
print("""
【包目录结构示例】
mypackage/
├── __init__.py # 包初始化文件
├── module1.py # 模块1
├── module2.py # 模块2
└── subpackage/ # 子包
├── __init__.py
└── module3.py
【__init__.py 的作用】
- 标识目录为 Python 包
- 包初始化代码
- 控制 from package import * 的行为
- 定义包的公共接口
""")
# 【导入本地包示例】
print("导入本地包:")
try:
from mypackage import greet
from mypackage.utils import helper
from mypackage.models import User
print(f" greet('World') = {greet('World')}")
print(f" helper.add(3, 5) = {helper.add(3, 5)}")
user = User("Alice", 25)
print(f" User: {user}")
except ImportError as e:
print(f" 导入失败: {e}")
print(" (需要创建 mypackage 目录)")
def main04_init_file():
"""
============================================================
4. __init__.py 详解
============================================================
"""
print("\n" + "=" * 60)
print("4. __init__.py 详解")
print("=" * 60)
print("""
【__init__.py 的常见用法】
1. 空文件(最简单)
- 仅用于标识包
2. 导入子模块
from .module1 import func1
from .module2 import Class2
3. 定义 __all__
__all__ = ['func1', 'Class2']
# 控制 from package import * 的行为
4. 包级别的变量和函数
__version__ = '1.0.0'
def package_func(): ...
5. 延迟导入(优化启动时间)
def __getattr__(name):
if name == 'heavy_module':
from . import heavy_module
return heavy_module
raise AttributeError
""")
def main05_relative_import():
"""
============================================================
5. 相对导入与绝对导入
============================================================
"""
print("\n" + "=" * 60)
print("5. 相对导入与绝对导入")
print("=" * 60)
print("""
【绝对导入】
from mypackage.module1 import func
import mypackage.subpackage.module3
【相对导入】(只能在包内使用)
from . import module1 # 当前包
from .module1 import func # 当前包的模块
from .. import module2 # 父包
from ..sibling import func # 兄弟包
【推荐】
- 对于外部包:使用绝对导入
- 对于包内模块:使用相对导入(更清晰)
【注意】
- 相对导入不能在顶层脚本中使用
- 运行脚本时使用 python -m package.module
""")
def main06_module_attributes():
"""
============================================================
6. 模块特殊属性
============================================================
"""
print("\n" + "=" * 60)
print("6. 模块特殊属性")
print("=" * 60)
import math
print("模块特殊属性:")
print(f" __name__: {math.__name__}")
print(f" __file__: {math.__file__}")
print(f" __doc__: {math.__doc__[:50]}...")
print(f" __package__: {math.__package__}")
# 【__name__ 的特殊用法】
print(f"\n--- __name__ 的用法 ---")
print(f"当前模块的 __name__: {__name__}")
print("""
if __name__ == '__main__':
# 只在直接运行时执行
main()
这个模式用于:
1. 区分直接运行和被导入
2. 编写可测试的模块
3. 提供命令行入口
""")
def main07_lazy_import():
"""
============================================================
7. 延迟导入与导入优化
============================================================
"""
print("\n" + "=" * 60)
print("7. 延迟导入与导入优化")
print("=" * 60)
# 【延迟导入】在需要时才导入
print("--- 延迟导入 ---")
def process_json(data):
import json # 只在调用时导入
return json.loads(data)
result = process_json('{"key": "value"}')
print(f"延迟导入 json: {result}")
# 【条件导入】
print(f"\n--- 条件导入 ---")
try:
import ujson as json
print("使用 ujson(更快)")
except ImportError:
import json
print("使用标准 json")
# 【importlib 动态导入】
print(f"\n--- 动态导入 ---")
import importlib
module_name = "math"
math_module = importlib.import_module(module_name)
print(f"动态导入 {module_name}: pi = {math_module.pi}")
# 重新加载模块
# importlib.reload(math_module)
def main08_namespace_packages():
"""
============================================================
8. 命名空间包
============================================================
"""
print("\n" + "=" * 60)
print("8. 命名空间包")
print("=" * 60)
print("""
【命名空间包】Python 3.3+
- 不需要 __init__.py
- 可以跨多个目录分布
- 用于大型项目或插件系统
【目录结构示例】
path1/
└── myns/
└── package1/
└── __init__.py
path2/
└── myns/
└── package2/
└── __init__.py
# myns 是命名空间包,可以同时导入:
from myns import package1
from myns import package2
【适用场景】
- 插件系统
- 多团队协作的大型项目
- 第三方扩展
""")
def main09_best_practices():
"""
============================================================
9. 最佳实践
============================================================
"""
print("\n" + "=" * 60)
print("9. 最佳实践")
print("=" * 60)
print("""
【导入顺序】(PEP 8)
1. 标准库导入
2. 第三方库导入
3. 本地模块导入
每组之间空一行
【示例】
import os
import sys
import numpy as np
import pandas as pd
from mypackage import mymodule
【命名规范】
- 模块名:小写,下划线分隔(my_module.py)
- 包名:小写,尽量不用下划线(mypackage)
- 避免与标准库同名
【避免循环导入】
- 重构代码结构
- 使用延迟导入
- 将导入放在函数内部
【其他建议】
- 优先使用绝对导入
- 避免 from module import *
- 使用 __all__ 控制公共接口
- 编写 __init__.py 提供简洁的 API
""")
if __name__ == "__main__":
main01_import_basics()
main02_module_search()
main03_package_structure()
main04_init_file()
main05_relative_import()
main06_module_attributes()
main07_lazy_import()
main08_namespace_packages()
main09_best_practices()
💬 讨论
使用 GitHub 账号登录后即可参与讨论