模块
python中创建了很多py文件,每个py文件我们官方说法就是 模块。
在模块可以编写一些代码。调用的时候只能在 当前模块中调用。那么能不能跨文件进行调用呢?
肯定是可以。
可以不同的代码放在不同的模块中,可以同过引用模块进行调用。
创建新项目

可以选择 新窗口 打开
创建模块
在项目上创建一个python文件
文件命名为 utils 用来存放一些自己定义的常用工具。
在文件中编写工具方法,将获取手机号的函数复制进来。
utils.py
# 导入python中的随机数生成模块import randomdef get_phone():"""生成一个随机的11手机号码, 手机号码中 前2位 ['13','14','15','17','18']:return:"""# 定义一个空的字符串 表示手机号phone=""# 定义手机号的支持的前两位pre_phone = ['13','14','15','17','18']# 随机从列表中选择一个 需要使用到随机函数p1 = random.choice(pre_phone) # 从列表中随机选择一个元素# print(p1)# 将随机获取的前两位放到手机号中phone=phone+p1# 生成9位随机的数字 (0,9) 循环9次for i in range(9):# 生成1位随机数n = random.randint(0,9)# print(n)# 将随机数字添加到手机号 n 位数字,数字不能直接跟字符串拼接 str(n) 将数字转换位字符串phone = phone+str(n)# 循环完成之后将电话号码返回return phonep = get_phone()print(f"生成随机电话 {p}")
调用模块中的方法 import
下面要在 testdemo.py 文件中调用 utils.py 中写的代码
# 导入 utils 模块import utils# 调用 utils 文件的get_phone() 函数phone = utils.get_phone()print(f'调用utils文件中获取电话号码的功能, {phone}')

testdemo.py 中的代码
- import utils
这一句 会将 utlis.py 文件中的内容加载到 testdemo.py 文件中。
也就是说,在执行 testdemo.py 文件的时候,因为 testdemo.py 中有 import utils 导入utils.py 文件,那么执行会先执行 utils.py 文件中的代码。因为utils.py 文件中有打印,所以在执行 testdemo.py 的时候会 打印两句。
模块中的调试
在代码编辑器中输入 main 会自动提示语句
utils.py
# 导入python中的随机数生成模块import randomdef get_phone():"""生成一个随机的11手机号码, 手机号码中 前2位 ['13','14','15','17','18']:return:"""# 定义一个空的字符串 表示手机号phone=""# 定义手机号的支持的前两位pre_phone = ['13','14','15','17','18']# 随机从列表中选择一个 需要使用到随机函数p1 = random.choice(pre_phone) # 从列表中随机选择一个元素# print(p1)# 将随机获取的前两位放到手机号中phone=phone+p1# 生成9位随机的数字 (0,9) 循环9次for i in range(9):# 生成1位随机数n = random.randint(0,9)# print(n)# 将随机数字添加到手机号 n 位数字,数字不能直接跟字符串拼接 str(n) 将数字转换位字符串phone = phone+str(n)# 循环完成之后将电话号码返回return phoneif __name__ == '__main__':p = get_phone()print(f"生成随机电话 {p}")
testdemo.py
# 导入 utils 模块import utilsif __name__ == '__main__':# 调用 utils 文件的get_phone() 函数phone = utils.get_phone()print(f'调用utils文件中获取电话号码的功能, {phone}')
再次执行 testdemo.py
完善代码
utils.py
# 导入python中的随机数生成模块import randomimport csvdef get_phone():"""生成一个随机的11手机号码, 手机号码中 前2位 ['13','14','15','17','18']:return:"""# 定义一个空的字符串 表示手机号phone=""# 定义手机号的支持的前两位pre_phone = ['13','14','15','17','18']# 随机从列表中选择一个 需要使用到随机函数p1 = random.choice(pre_phone) # 从列表中随机选择一个元素# print(p1)# 将随机获取的前两位放到手机号中phone=phone+p1# 生成9位随机的数字 (0,9) 循环9次for i in range(9):# 生成1位随机数n = random.randint(0,9)# print(n)# 将随机数字添加到手机号 n 位数字,数字不能直接跟字符串拼接 str(n) 将数字转换位字符串phone = phone+str(n)# 循环完成之后将电话号码返回return phonedef get_area():"""生成随机的6位地区信息:return: 6个数字字符串"""# 从csv文件中读取所有的地区码,随机选择一个# 定义空的list 用来存放地区码area_code=[]with open('gb2260.csv',mode='r',encoding='utf8') as file:lines = csv.reader(file)for line in lines:# 每个地区码 都放在list 中area_code.append(line)# 随机从 所有地区码中选择一个code = random.choice(area_code)# code 值选择出来是 一个list 需要将list 转换位字符串code_str = ''.join(code) # ''.join(code) 将list 转换位字符串# 将随机选择的code 返回return code_strdef get_birth():"""生成随机的 出生年月日 1960-2022出生:return:"""# 年份year = random.randint(1960,2022)# 月份month = random.randint(1,12)# 日# 考虑闰年,月份# 如果年份是闰年,并且月份2月, 有29天if year%4 == 0 and month == 2:day = random.randint(1,29)# 在 1,3,5,7,8,10,12 月中 有31天elif month in [1,3,5,7,8,10,12]:day = random.randint(1,31)elif month in [4,6,9,11]:day = random.randint(1,30)# 如果以上都不是 就是 平年的2月份else:day = random.randint(1,28)# 如果天为个位数 前面添加0if day<10:day = "0"+str(day)# 月份前 01, 02if month < 10:month = "0" + str(month)# 返回年月日return f'{year}{month}{day}'def get_last():"""最后4位:return:"""pre_3=""for i in range(3):n = random.randint(0,9)pre_3 = pre_3+str(n)last = random.choice(['0','1','2','3','4','5','6','7','8','9','X'])# 返回return f'{pre_3}{last}'if __name__ == '__main__':p = get_phone()print(f"生成随机电话 {p}")
在testdemo.py 中引用
# 导入 utils 模块import utilsdef get_id():"""生成身份证id:return:"""# 调用 utils 中定义函数area_code = utils.get_area()ymd_code = utils.get_birth()last_code = utils.get_last()return area_code+ymd_code+last_codeif __name__ == '__main__':# 调用 utils 文件的get_phone() 函数phone = utils.get_phone()print(f'调用utils文件中获取电话号码的功能, {phone}')user_id = get_id()print(f'生成的身份证id {user_id}')
运行testdemo.py代码
所有的代码
main.zip
导入模块的两种方式
使用import 导入
创建python 文件
demo.py
def f1():print('demo文件中的f1 函数')if __name__ == '__main__':f1()
在main.py 文件引用 demo.py 中定义的f1函数。
main.py
import demoif __name__ == '__main__':demo.f1()
使用from…import…导入
也可以使用 from … import… 方式来进行导入。
demo.py
def f1():print('demo文件中的f1 函数')def f2():print('demo文件中的f2 函数')if __name__ == '__main__':f1()
在main.py 文件中导入
# 使用 from 方式来导入 demo 文件中的 f2from demo import f2if __name__ == '__main__':# 可以直接使用f2()
使用 import 和 from … import 功能都是一样的。
from… import * 导入所有
main.py 中引入 demo.py 文件中所有的函数
main.py
# * 导入demo 文件中所有的函数from demo import *if __name__ == '__main__':f2()f1()
使用 import 导入可以,使用from … import … 的方式也行。两种方法都可以使用。使用的时候根据自己的使用习惯即可。
比如生成随机数,你可以这样写
import randomprint(random.randomint(1,10))
也可以使用from的方式
from random import randintprint(randint(1,10))
包

目前来说,项目文件都在根目录下,当编写的代码越来越多的时候,需要将代码按照不同的功能放在不同的文件夹。这些不同文件夹在Python中称为 包
创建Python包

开发过程中,一些常用的函数都会放在 common 包,所以为这个包 命名为 common
在common包中创建 file.py 文件,这个文件后面主要用来解析一些数据文件。
在files.py 文件中 编写代码。
common/files.py
def parse_csv():print("files中解析csv文件的函数")if __name__ == '__main__':parse_csv()
引入包中的文件
引入包中的文件原理跟引入模块中函数原理一样,通过import 或者 from方式来引用。
import导入
在main.py 中导入
# import导入。需要跟上包的路径 common.files as 给路径起别名(别名可以随意)import common.files as fif __name__ == '__main__':# 调用包中文件的函数f.parse_csv()
from 导入
也可以通过from 的方式来导入包
# from 包.文件的路径 导入from common.files import parse_csvif __name__ == '__main__':# 调用包中文件的函数parse_csv()
不同的包中引用
创建 一个 testcases 的包,在testcase 包中创建 test_demo.py 文件。
在test_demo.py 文件中 引用 common包下 files.py 文件中定义的函数。
testcases/test_demo.py
import common.files as ffrom common.files import parse_csvif __name__ == '__main__':f.parse_csv()parse_csv()
运行都可以引用到
加强练习
定义解析csv文件
common/files.py
import csvdef parse_csv(filename):"""通过传入一个csv文件,将csv文件中的内容解析出来存放到列表中返回。:param filename: 传入的文件路径:return:"""# 定义空的列表存放csv文件中的数据data = []with open(filename,mode='r',encoding='utf8') as f:lines = csv.reader(f)for line in lines:# 将读取出来的数据放到data中data.append(line)# 数据读取完成之后return data
files.py 文件中 传入csv文件来测试 上面编写的函数是否正常。
import csvdef parse_csv(filename):"""通过传入一个csv文件,将csv文件中的内容解析出来存放到列表中返回。:param filename: 传入的文件路径:return:"""# 定义空的列表存放csv文件中的数据data = []with open(filename,mode='r',encoding='utf8') as f:lines = csv.reader(f)for line in lines:# 将读取出来的数据放到data中data.append(line)# 数据读取完成之后return dataif __name__ == '__main__':# 检查一下 parse_csv 函数是否正常运行 使用绝对路径 可以解析出这个文件的内容。# data = parse_csv(r'C:\Users\zengy\PycharmProjects\pythonProject10\gb2260.csv')import os# 获取当前文件所在的目录 获取目录名dir = os.path.dirname(__file__)print(dir)# 找到项目的根目录 获取目录名project_root = os.path.dirname(dir)print('项目根目录',project_root)# csv文件路径 join 方法可以将两个路径拼接到一起csvfile = os.path.join(project_root,'gb2260.csv')print(f'csv 文件路径: {csvfile}')data = parse_csv(csvfile)print(data)
common/files.py
import csvimport osdef get_project_root():"""在解析文件的时候,需要拼接文件的路径,这个函数 返回项目的根目录:return:"""# 获取当前文件所在的目录dir = os.path.dirname(__file__) # 找common 目录print(dir) # C:\Users\zengy\PycharmProjects\pythonProject10\common# 找到项目的根目录project_root = os.path.dirname(dir) # common的上级目录 当前项目的根目录print(project_root) # C:\Users\zengy\PycharmProjects\pythonProject10return project_rootdef parse_csv(filename):"""通过传入一个csv文件,将csv文件中的内容解析出来存放到列表中返回。:param filename: 传入的文件路径:return:"""# 定义空的列表存放csv文件中的数据data = []with open(filename,mode='r',encoding='utf8') as f:lines = csv.reader(f)for line in lines:# 将读取出来的数据放到data中data.append(line)# 数据读取完成之后return dataif __name__ == '__main__':# 检查一下 parse_csv 函数是否正常运行 使用绝对路径 可以解析出这个文件的内容。# data = parse_csv(r'C:\Users\zengy\PycharmProjects\pythonProject10\gb2260.csv')# 获取到项目的根目录project_root = get_project_root()# csv文件路径 join 方法可以将两个路径拼接到一起csvfile = os.path.join(project_root,'gb2260.csv')print(f'csv 文件路径: {csvfile}')data = parse_csv(csvfile)print(data)
现在在test_demo.py 文件解析 gb2260.csv 文件
通过获取项目的根目录来拼接路径 进行操作。
testcases/test_demo.py
import osfrom common.files import parse_csv,get_project_rootif __name__ == '__main__':# 拼接csv路径# 1. 拿到项目的根目录root = get_project_root()# 2. 拼接csv文件csvfile = os.path.join(root,'gb2260.csv')# 解析文件路径data = parse_csv(csvfile)print(data)
多层目录引用文件
testcases/test_csv/test_file.py
import osfrom common.files import parse_csv,get_project_rootif __name__ == '__main__':# 拼接csv路径# 1. 拿到项目的根目录root = get_project_root()# 2. 拼接csv文件csvfile = os.path.join(root,'gb2260.csv')# 解析文件路径data = parse_csv(csvfile)print(data)
在这个文件,通过调用封装好的 获取项目根目录路径的方法 在任何地方调用,都可以取到项目的根目录,再进行路径拼接。就可以调用里面的方法。
项目数据文件解析
在做一个项目的时候,需要对单接口做csv数据参数化,每个接口需要准备对应的csv文件。如果有很多csv文件,需要将csv文件放在对应目录中。
在项目中 创建 testdata 目录,这个目录用来存放测试数据。
创建目录
目录名称为 testdata
在testdata 目录中放入 csv文件
解析testdata 目录中的csv文件
testcases/test_demo.py
import osfrom common.files import parse_csv,get_project_rootif __name__ == '__main__':# 拼接csv路径# 1. 拿到项目的根目录# root = get_project_root()# # 2. 拼接csv文件# csvfile = os.path.join(root,'gb2260.csv')# # 解析文件路径# data = parse_csv(csvfile)# print(data)# 1. 获取系统的根目录root = get_project_root()# 2. 拿到文件路径topic_csv = os.path.join(root,'testdata/testtopic.csv')# 解析文件data = parse_csv(topic_csv)print(data)

附件
所有对应的代码
demo.zip
作业
在项目的common包下创建 utils.py 文件 实现生成手机号码 和身份证id的函数
def generate_id():"""生成一个随机的身份证号 并返回:return:"""def generate_phone():"""生成一个随机的 11位手机号码:return:"""
答案
def generate_phone():"""生成一个随机的 11位手机号码:return:"""#确定前两位手机pre_2 =["13","14","15","16","17","18"]# 随机选择一个元素p2 = random.choice(pre_2)# 生成9位随机数字l9 = ""for i in range(9):# 每次循环生成一个随机数字n = random.randint(0,9)l9 = l9+str(n) # 将数字转换为字符串之后进行拼接return p2+l9if __name__ == '__main__':phone = generate_phone()print(phone)
import randomfrom common.files import get_project_root,parse_csvimport osdef generate_id():"""生成一个随机的身份证号 并返回:return:"""# 拿到项目根目录root = get_project_root()# 拼接csv文件file_csv = os.path.join(root,'gb2260.csv')# 通过解析csv文件获取所有的地区编码all_code = parse_csv(file_csv)print(all_code)# 随机选择一个列表code = random.choice(all_code)print(code)# 列表转换为字符串p6 = ''.join(code)print(p6)# 设置出生年月日year = random.randint(1960,2020)month = random.randint(1,12)# 闰年 2月份 29天if year%4==0 and month == 2:day=random.randint(1,29)# 31天elif month in [1,3,5,7,8,10,12]:day = random.randint(1,31)elif month in [4,6,9,11]:day = random.randint(1,30)# 平年的2月 28天else:day = random.randint(1,28)# month ,day 小于10 前面补0if month<10:#转换为字符串month = f'0{month}'if day <10:day = f'0{day}'# 合并年月日 转换为字符串ymd = f'{year}{month}{day}'print(ymd)# 获取最后4位 最后一位Xl3 = ""for i in range(3):n = random.randint(0,9)# 数字转换字符串 拼接l3 = l3+str(n)l1 = list(range(10))l1.append("X") # [0,1,2,3,4,5,6,7,8,9,"X"]print(l1)l = random.choice(l1) # 最后1位l4 = l3 + str(l) # 最后4位return f'{p6}{ymd}{l4}'if __name__ == '__main__':id=generate_id()print(id)
最终文件
import randomfrom common.files import get_project_root,parse_csvimport osdef generate_id():"""生成一个随机的身份证号 并返回:return:"""# 拿到项目根目录root = get_project_root()# 拼接csv文件file_csv = os.path.join(root,'gb2260.csv')# 通过解析csv文件获取所有的地区编码all_code = parse_csv(file_csv)# print(all_code)# 随机选择一个列表code = random.choice(all_code)# print(code)# 列表转换为字符串p6 = ''.join(code)#print(p6)# 设置出生年月日year = random.randint(1960,2020)month = random.randint(1,12)# 闰年 2月份 29天if year%4==0 and month == 2:day=random.randint(1,29)# 31天elif month in [1,3,5,7,8,10,12]:day = random.randint(1,31)elif month in [4,6,9,11]:day = random.randint(1,30)# 平年的2月 28天else:day = random.randint(1,28)# month ,day 小于10 前面补0if month<10:month = f'0{month}'if day <10:day = f'0{day}'# 合并年月日 转换为字符串ymd = f'{year}{month}{day}'# print(ymd)# 获取最后4位 最后一位Xl3 = ""for i in range(3):n = random.randint(0,9)# 数字转换字符串 拼接l3 = l3+str(n)l1 = list(range(10)) #生成[0,1,2,3,4,5,6,7,8,9] 列表l1.append("X") # [0,1,2,3,4,5,6,7,8,9,"X"]# print(l1)l = random.choice(l1) # 随机从列表中选择一个l4 = l3 + str(l) # 最后4位return f'{p6}{ymd}{l4}'def generate_phone():"""生成一个随机的 11位手机号码:return:"""#确定前两位手机pre_2 =["13","14","15","16","17","18"]# 随机选择一个元素p2 = random.choice(pre_2)# 生成9位随机数字l9 = ""for i in range(9):# 每次循环生成一个随机数字n = random.randint(0,9)l9 = l9+str(n) # 将数字转换为字符串之后进行拼接return p2+l9if __name__ == '__main__':id = generate_id()print(f'最终生成的id:{id}')


