Python3 模块与包

模块(module)就是一个 .py 文件;包(package)是存放多个模块的目录。把功能拆分到模块中可以复用代码、避免命名冲突,是组织大型程序的基本方式。

模块概念与导入

import math
print(math.sqrt(16))     # 输出:4.0
print(math.pi)           # 输出:3.141592653589793

模块第一次导入时执行一次,重复 import 不会重复执行。

from...import 与 as 别名

from math import sqrt, pi
print(sqrt(9))           # 输出:3.0

import math as m
print(m.floor(3.7))      # 输出:3

模块搜索路径 sys.path

导入时 Python 按 sys.path 列出的目录依次查找同名 .py 文件:

import sys
for p in sys.path[:3]:
    print(p)   # 通常含当前目录、标准库目录、第三方包目录等

当前脚本所在目录通常在其中,把自己写的模块放同目录即可被导入。

if name == 'main'

__name__ 在文件被直接运行时是 '__main__',被 import 时是模块名。据此区分两种场景,让测试代码只在直接运行时执行:

# mymath.py
def add(a, b):
    return a + b
if __name__ == '__main__':
    # 只有 python mymath.py 直接运行时才执行
    print(add(1, 2))      # 输出:3

在其他文件中 import mymath 时,这段代码不会执行:

import mymath
print(mymath.add(2, 3))   # 输出:5(不打印上面的测试输出)

自定义模块与 dir()

自己写一个 .py 文件就是模块;dir() 可列出模块或对象的全部名字:

# utils.py
def hello():
    print("hi")

# 在另一个文件中:
# import utils
# utils.hello()      # 输出:hi
# print(dir(utils))  # 输出含 'hello' 的名字列表

包(package)与 init.py

把模块放进带 __init__.py 的目录即构成包,可分层组织代码:

mypkg/
├── __init__.py      # 包的初始化文件(可为空)
├── math_utils.py
└── str_utils.py

使用方式:from mypkg import math_utils,或 from mypkg.math_utils import add

相对导入一句话

包内部互相引用用 . 开头的相对导入,如 from . import str_utils 表示导入同包下的兄弟模块。

常用标准模块速览

标准库"开箱即用",常用模块举例如下:

import os, sys, math, random, datetime, json
import re, collections, heapq, logging, hashlib

print(random.randint(1, 10))       # 输出:1 到 10 之间随机整数
print(json.dumps({"a": 1}))        # 输出:{"a": 1}
print(datetime.date.today())       # 输出:今天的日期

小结:模块化让代码可复用、易维护;弄清导入方式、sys.path 与 if __name__ == '__main__',就能正确组织并运行多文件程序。

笔记加载中…