在 Python 中,为了编写易于维护的代码,我们会将代码拆分放到不同的文件里,这样每个文件包含的代码相对就会减少。在 Python 中,一个 .py 文件称为一个模块(Module)。
代码模块化的好处:
(1)简单化问题求解
降低代码复杂度,将代码拆分到不同文件中,每个文件只需要考虑其子问题的求解,不用考虑整个问题的求解。
(2)提高代码可维护性
减少代码间的依赖,降低由修改一个文件对别的文件的影响,提高不同文件间并行开发的可能性。
(3)提高代码间的可重用性
一个模块编写完成后,可以被其他模块引用。在编程时,可以引入其他模块,包括Python内置模块和第三方模块。提高代码的复用性和开发效率。
(4)减少代码冲突
模块提供了一个独立的命名空间,独立命名空间的好处是可以避免函数名和变量名冲突。相同名字的函数和变量可以放在不同的模块中。因此,我们自己在编写模块时,不必考虑名字会与其他模块冲突。但是也要注意,尽量不要与内置函数名字冲突。
一、模块的创建
创建一个.py文件,将实现代码逻辑放到该文件中,即完成模块的创建。一个.py文件即是一个模块(Module)。
# utils.py模块
def max_num(a, b):
if a >= b:
return a
else:
return b
def min_num(a, b):
if a > b:
return b
else:
return a
二、模块的导入
1、import
模块创建完后,可以用import关键字引入,如:import utils
执行该命令,Python会从以下步骤中去寻找对应的模块:
(1)在当前目录下搜索。
(2)在环境变量PYTHONPATH中一次搜索该模块。
(3)在Python安装路径下的lib库中查找。
上述路径可以使用sys.path获取,位于sys模块中。sys.path是Python的一个环境变量,是Python用于搜索模块的路径列表。
import sys
print(sys.path)
输出:
['/tmp/box/24', '/usr/local/python3/lib/python39.zip', '/usr/local/python3/lib/python3.9', '/usr/local/python3/lib/python3.9/lib-dynload', '/usr/local/python3/lib/python3.9/site-packages']
为了让创建的模块能够被找到,需要将模块放到上述路径中的一个,因为 Python 只会在这些路径中去查找模块,如果没有将模块创建在这些路径中,则找不到对应的模块,也就没办法应用模块中的对象和方法了。
#导入模块utils
import utils
print(utils.max_num(4, 5))
print(utils.min_num(4, 5))
输出:
5
4
2、from mudule_name import name(s)
直接导入模块中的对象,格式:from 模块名 import 方法名/对象名
from utils import max_num, min_num
print(max_num(4, 5))
print(min_num(4, 5))
输出:
5
4
使用 from 模块名 import * 来引入该模块下所有对象
from utils import *
print(max_num(4, 5))
print(min_num(4, 5))
输出:
5
4
3、from module_name import names as alt_name
模块中的对象和方法也可命名为别名,格式:from 模块名 import 方法名1/对象名1 as 别名1,方法名2/对象名2 as 别名2,...
from utils import max_num as max_n, min_num as min_n
print(max_n(4, 5))
print(min_n(4, 5))
输出:
5
4
4、import module_name as alt_name
可以为整个模块命名别名,如:
import utils as ul
print(ul.max_num(4, 5))
print(ul.min_num(4, 5))
输出:
5
4
5、包含单个类的模块引入
#创建模块car.py,包含一个Car类
class Car:
def __init__(self, mk, md, y, c):
self.make = mk
self.model = md
self.year = y
self.color = c
self.mileage = 0
def get_description(self):
description = f'{self.year} {self.color} {self.make} {self.model}'
print(description)
def get_mileage(self):
print(f"This car has {self.mileage} miles on it")
def update_mileage(self, mile):
self.mileage = mile
引入Car类:
from car import Car
my_car = Car('audi', 'a4', 2016, 'white')
my_car.get_description()
my_car.update_mileage(30)
my_car.get_mileage()
输出:
2016 white audi a4
This car has 30 miles on it
6、包含多个类的模块引入
#创建car.py模块,包括Car类和其继承类ElectricCar
class Car:
def __init__(self, mk, md, y, c):
self.make = mk
self.model = md
self.year = y
self.color = c
self.mileage = 0
def get_description(self):
description = f'{self.year} {self.color} {self.make} {self.model}'
print(description)
def get_mileage(self):
print(f"This car has {self.mileage} miles on it")
def update_mileage(self, mile):
self.mileage = mile
class ElectricCar(Car):
def __init__(self, mk, md, y, c):
super().__init__(mk, md, y, c)
self.battery_size = 100
def get_battery(self):
print(f"This car has {self.battery_size} -kWh battery.")
导入多个类:
from car import ElectricCar, Car
my_car = Car('audi', 'a4', 2016, 'white')
my_car.update_mileage(30)
my_car.get_mileage()
my_tesla = ElectricCar('tesla', 'model 3', 2018, 'white')
my_tesla.get_description()
my_tesla.get_battery()
输出:
This car has 30 miles on it
2018 white tesla model 3
This car has 100 -kWh battery.
导入整个模块,使用import car
导入模块中所有类,使用 from car import *
三、包
随着模块的增多,所有模块放同一个目录下,管理起来困难,因此引入了包的概念。
1、包的创建
对于具有相似名称或相似功能的模块,可以使用Python对模块分组管理的功能,使用操作系统文件分层文件结构,将模块放在一个目录文件夹中,就形成了一个包。
如图,在文件夹 pkg中,存在utils1.py和utils2.py两个文件。(pkg是一个包,utils1.py和utils2.py是两个模块)
#utils1.py模块
def max_num(a, b):
if a >= b:
return a
else:
return b
def min_num(a, b):
if a > b:
return b
else:
return a
#utils2.py模块
def sum_num(a, b):
return a + b
def abs_num(a):
if a >= 0:
return a
else:
return -a
2、import module_names[,...]
使用 import 包名.模块名 引入包中的模块
import pkg.utils1,pkg.utils2
print(pkg.utils1.max_num(4, 5))
print(pkg.utils2.sum_num(4, 5))
输出:
5
9
3、from pakage_name import module_name[,...]
使用 from 包名 import 模块名1,模块名2 引入包中的模块
from pkg import utils1, utils2
print(utils1.max_num(4, 5))
print(utils2.sum_num(4, 5))
输出:
5
9
4、from module_name import names[,...]
引入包中模块的对象,使用 from 包名.模块名 import 对象名
from pkg.utils1 import max_num
print(max_num(4, 5))
输出:
5
5、from module_name import names as alt_name
为包中模块的对象创建别名,使用 from 包名.模块名 import 对象名 as 别名
6、from pakage_name import module_name as alt_name
为包中整个模块创建别名,使用 from 包名 import 模块名 as 别名
或 import 包名.模块名 as 别名