通过使用Python语言批量生成Excel格式的测试数据
一、源码
import os
import random
import time
import pandas as pd
from tqdm import tqdm
class DataGenerator:
def __init__(self, rows, batch_size=1000):
"""数据生成器类,用于生成指定行数的随机数据。
Args:
rows (int): 要生成的数据行数。
batch_size (int, optional): 每批次生成的数据量,默认为 1000。
"""
self.rows = rows
self.batch_size = batch_size
@staticmethod
def generate_name():
"""生成随机姓名。
Returns:
str: 随机生成的姓名。
"""
first_names = ['赵', '钱', '孙', '李', '周', '吴', '郑', '王', '诸葛', '东方']
last_names = ['舒梅', '莉梦', '素艺', '玲羽', '爽莉', '淑玥', '静洁', '瑶茜', '琴瑶', '洁颖', '岳毅', '龙力',
'胜康', '铭怀', '鑫晖', '奇国', '晨畅', '玮熠', '朔凝', '逸敏']
# 随机选择姓和名
first_name = random.choice(first_names)
max_last_name_length = min(4, 5 - len(first_name))
last_name_length = random.randint(1, max_last_name_length)
last_name = ''.join(random.choice(last_names) for _ in range(last_name_length))
full_name = first_name + last_name
# 随机生成的姓名长度不能超过4个字符
while len(full_name) > 4:
last_name_length -= 1
if last_name_length < 1:
break
last_name = ''.join(random.choice(last_names) for _ in range(last_name_length))
full_name = first_name + last_name
return full_name
@staticmethod
def generate_phone_number():
"""生成随机手机号码。
Returns:
str: 随机生成的手机号码。
"""
second = random.randint(1, 9)
third = random.randint(1, 9)
suffix = random.randint(10000000, 99999999)
return f"1{second}{third}{suffix}"
@staticmethod
def generate_address():
"""生成随机地址。
Returns:
str: 随机生成的地址。
"""
cities = ["北京", "上海", "南京", "天津", "深圳"]
district = random.randint(1, 20)
street = random.randint(1, 1000)
return f"{random.choice(cities)}市{district}区{street}号"
@staticmethod
def generate_email():
"""生成随机邮箱。
Returns:
str: 随机生成的邮箱。
"""
domains = ["@qq.com", "@dingtalk.com", "@163.com", "@139.com", "@outlook.com", "@sohu.com", "@aliyun.com"]
username = ''.join(random.choices('abcdefghijklmnopqrstuvwxyz0123456789', k=10))
domain = random.choice(domains)
return f"{username}{domain}"
def generate_data_batch(self, batch_size, generated_rows):
"""生成一批次的数据。
Args:
batch_size (int): 批次的数据量。
generated_rows (int): 已生成的总行数。
Returns:
list: 生成的数据列表。
"""
cities = ["北京", "上海", "南京", "天津", "深圳"]
genders = ["男", "女"]
ages = [i for i in range(1, 101)]
jobs = ["学生", "老师", "社会人员"]
educations = ["小学毕业", "初中毕业", "高中毕业", "高职学历", "大学专科", "大学本科", "硕士学历",
"博士学历", "博士以上"]
data = []
for _ in range(batch_size):
if generated_rows + self.batch_size > self.rows:
current_batch_size = self.rows - generated_rows
if current_batch_size <= 0:
break
else:
current_batch_size = min(self.batch_size, self.rows - generated_rows)
current_row = len(data) + 1
name = self.generate_name()
age = random.choice(ages)
city = random.choice(cities)
gender = random.choice(genders)
job = random.choice(jobs)
email = self.generate_email()
phone_number = self.generate_phone_number()
address = self.generate_address()
education = random.choice(educations)
data.append([
current_row, name, age, city, gender, job, email, phone_number, address, education
])
return data
@staticmethod
def save_to_excel(data, file_path):
"""将数据保存到Excel文件中。
Args:
data (list): 要保存的数据列表。
file_path (str): 文件路径。
"""
df = pd.DataFrame(
data,
columns=["编号", "姓名", "年龄", "城市", "性别", "职业", "邮箱", "电话", "地址", "学历"]
)
df.to_excel(file_path, index=False)
def generate_and_save_batch(self, folder_path):
"""生成并保存数据批次。
Args:
folder_path (str): 文件夹路径。
Returns:
str: 生成的Excel文件路径。
"""
if self.rows <= 0:
print("请输入大于0的行数")
return
total_batches = (self.rows - 1) // self.batch_size + 1
file_name = f"data_{time.strftime('%Y%m%d%H%M%S')}.xlsx"
file_path = os.path.join(folder_path, file_name)
with tqdm(total=self.rows, desc=f"数据生成进度:0/{self.rows}") as pbar:
generated_rows = 0
data = []
while generated_rows < self.rows:
current_batch_size = min(self.batch_size, self.rows - generated_rows)
batch_data = self.generate_data_batch(current_batch_size, generated_rows)
generated_rows += current_batch_size
data.extend(batch_data)
self.save_to_excel(data, file_path)
pbar.set_description(f"数据生成进度:{generated_rows}/{self.rows}")
pbar.update(current_batch_size)
time.sleep(0.1)
return file_path
if __name__ == "__main__":
rows = int(input("请输入要生成的行数:"))
folder_path = input("请输入文件夹路径:")
try:
if folder_path:
os.makedirs(folder_path, exist_ok=True)
except OSError:
print("创建文件夹失败")
exit(1)
start_time = time.time()
print("\n数据生成进度:")
data_generator = DataGenerator(rows)
generated_file = data_generator.generate_and_save_batch(folder_path)
end_time = time.time()
print(f"\nExcel数据已成功生成并保存到文件:{os.path.abspath(generated_file)}")
print(f"共生成 {rows} 行数据,总耗时:{end_time - start_time:.2f} 秒")
print(f"文件名:{os.path.basename(generated_file)}")
二、代码分析
2.1导入模块和库
import os
import random
import time
import pandas as pd
from tqdm import tqdm
这段代码使用了Python的内置模块os、random和time,以及第三方库pandas和tqdm。
import os语句导入了os模块,它提供了与操作系统进行交互的功能,例如创建文件夹、列出目录中的文件等。
import random语句导入了random模块,它提供了生成随机数的功能,例如生成随机整数、随机选择列表中的元素等。
import time语句导入了time模块,它提供了与时间相关的功能,例如获取当前时间、暂停程序执行等。
import pandas as pd语句导入了pandas库,并将其简化为pd,pandas是一个用于数据分析和处理的强大工具,它提供了高性能、易于使用的数据结构和数据分析工具。
from tqdm import tqdm语句导入了tqdm库中的tqdm函数,它提供了在循环中显示进度条的功能,可以让程序执行过程更加可视化。
总结:该代码段导入了一些常用的Python模块和库,它们提供了操作系统交互、随机数生成、时间处理、数据分析以及显示进度条的功能。
2.2 生成指定行数的随机数据
class DataGenerator:
def __init__(self, rows, batch_size=1000):
"""数据生成器类,用于生成指定行数的随机数据。
Args:
rows (int): 要生成的数据行数。
batch_size (int, optional): 每批次生成的数据量,默认为 1000。
"""
self.rows = rows
self.batch_size = batch_size
这段代码定义了一个名为DataGenerator的类,用于生成指定行数的随机数据。
在类的__init__方法中,接受两个参数:rows和batch_size。rows是要生成的数据行数,batch_size是每批次生成的数据量,默认为1000。
在方法体内,self.rows = rows将传入的rows赋值给实例变量self.rows,以便后续可在类的其他方法中使用。self.batch_size = batch_size将传入的batch_size赋值给实例变量self.batch_size。
该类的作用是根据指定的行数和批次大小生成随机数据,可以通过实例化该类并调用相应的方法来使用。
2.3随机生成姓名
@staticmethod
def generate_name():
"""生成随机姓名。
Returns:
str: 随机生成的姓名。
"""
first_names = ['赵', '钱', '孙', '李', '周', '吴', '郑', '王', '诸葛', '东方']
last_names = ['舒梅', '莉梦', '素艺', '玲羽', '爽莉', '淑玥', '静洁', '瑶茜', '琴瑶', '洁颖', '岳毅', '龙力',
'胜康', '铭怀', '鑫晖', '奇国', '晨畅', '玮熠', '朔凝', '逸敏']
# 随机选择姓和名
first_name = random.choice(first_names)
max_last_name_length = min(4, 5 - len(first_name))
last_name_length = random.randint(1, max_last_name_length)
last_name = ''.join(random.choice(last_names) for _ in range(last_name_length))
full_name = first_name + last_name
# 随机生成的姓名长度不能超过4个字符
while len(full_name) > 4:
last_name_length -= 1
if last_name_length < 1:
break
last_name = ''.join(random.choice(last_names) for _ in range(last_name_length))
full_name = first_name + last_name
return full_name
这段代码定义了一个名为generate_name的静态方法,用于生成随机的姓名。
在方法体内,首先定义了一个first_names列表,其中包含了一些姓氏,例如'赵'、'钱'、'孙'等。接着定义了一个last_names列表,其中包含了一些名字的部分,如'舒梅'、'莉梦'、'素艺'等。
然后通过以下步骤生成随机的姓名:
- 从
first_names列表中随机选择一个姓氏,赋值给first_name变量。 - 计算可选名字的最大长度,取4与5减去
first_name长度的较小值。将其赋值给max_last_name_length变量。 - 生成一个随机整数,范围在1到
max_last_name_length之间,表示名字的长度。将其赋值给last_name_length变量。 - 使用列表推导式和
random.choice函数,从last_names列表中随机选择last_name_length个名字的部分,并将它们连接成一个字符串,赋值给last_name变量。 - 将
first_name和last_name拼接到一起,得到完整的姓名,赋值给full_name变量。 - 如果生成的姓名长度超过4个字符,则进入循环,每次将
last_name_length减1,并重新生成last_name和full_name,直到长度不超过4个字符或者last_name_length小于1为止。
最后,返回生成的完整姓名。
该静态方法可以直接通过类名调用,例如DataGenerator.generate_name(),它会返回一个随机生成的姓名。
2.4随机生成手机号
@staticmethod
def generate_phone_number():
"""生成随机手机号码。
Returns:
str: 随机生成的手机号码。
"""
second = random.randint(1, 9)
third = random.randint(1, 9)
suffix = random.randint(10000000, 99999999)
return f"1{second}{third}{suffix}"
当调用generate_phone_number方法时,会执行以下步骤:
- 使用
random.randint(1, 9)生成一个1到9之间的随机整数,将它赋值给变量second。这个数字表示手机号码的第二位。 - 使用
random.randint(1, 9)再次生成一个1到9之间的随机整数,将它赋值给变量third。这个数字表示手机号码的第三位。 - 使用
random.randint(10000000, 99999999)生成一个8位数的随机整数,该整数作为手机号码后缀部分,将它赋值给变量suffix。 - 使用格式化字符串(f-string)将
second、third和suffix拼接成一个完整的手机号码字符串。格式为"1{second}{third}{suffix}"。其中,'1'表示手机号码的开头。 - 返回生成的手机号码字符串。
该静态方法可以直接通过类名调用,通过调用DataGenerator.generate_phone_number(),可以随机生成一个手机号码。例如,可能返回"13812345678"或"15198765432"等不同的手机号码。
2.5生成随机地址
@staticmethod
def generate_address():
"""生成随机地址。
Returns:
str: 随机生成的地址。
"""
cities = ["北京", "上海", "南京", "天津", "深圳"]
district = random.randint(1, 20)
street = random.randint(1, 1000)
return f"{random.choice(cities)}市{district}区{street}号"
这段代码定义了一个名为generate_address的静态方法,用于生成随机的地址。
在方法体内,首先定义了一个cities列表,其中包含了一些城市名称,例如"北京"、"上海"、"南京"、"天津"和"深圳"。
接着使用random.randint(1, 20)函数生成一个1到20之间的随机整数,表示地址的区(district)部分,将其赋值给变量district。
然后使用random.randint(1, 1000)函数生成一个1到1000之间的随机整数,表示地址的街道(street)部分,将其赋值给变量street。
最后,使用格式化字符串(f-string)将随机选择的城市、区和街道拼接成一个完整的地址字符串,格式为"{random.choice(cities)}市{district}区{street}号"。其中,{random.choice(cities)}会从cities列表中随机选择一个城市名称。
返回生成的随机地址字符串。
该静态方法可以直接通过类名调用,例如DataGenerator.generate_address(),它会返回一个随机生成的地址。例如,可能返回"上海市15区567号"、"南京市8区233号"等不同的地址。
2.6生成随机邮箱
@staticmethod
def generate_email():
"""生成随机邮箱。
Returns:
str: 随机生成的邮箱。
"""
domains = ["@qq.com", "@dingtalk.com", "@163.com", "@139.com", "@outlook.com", "@sohu.com", "@aliyun.com"]
username = ''.join(random.choices('abcdefghijklmnopqrstuvwxyz0123456789', k=10))
domain = random.choice(domains)
return f"{username}{domain}"
这段代码定义了一个名为generate_email的静态方法,用于生成随机的邮箱地址。
在方法体内,首先定义了一个domains列表,其中包含了一些常见的邮箱域名,例如"@qq.com"、"@dingtalk.com"、"@163.com"等。
接着使用random.choices('abcdefghijklmnopqrstuvwxyz0123456789', k=10)函数生成一个长度为10的随机字符串,由小写字母和数字组成,将它赋值给变量username,表示邮箱的用户名部分。
然后使用random.choice(domains)函数从domains列表中随机选择一个邮箱域名,将它赋值给变量domain,表示邮箱的域名部分。
最后,使用格式化字符串(f-string)将随机生成的用户名和邮箱域名拼接成一个完整的邮箱地址字符串,格式为"{username}{domain}"。
返回生成的随机邮箱地址字符串。
该静态方法可以直接通过类名调用,例如DataGenerator.generate_email(),它会返回一个随机生成的邮箱地址。例如,可能返回"abc123xyz@qq.com"、"helloworld@163.com"等不同的邮箱地址。
2.7生成一批数据
def generate_data_batch(self, batch_size, generated_rows):
"""生成一批次的数据。
Args:
batch_size (int): 批次的数据量。
generated_rows (int): 已生成的总行数。
Returns:
list: 生成的数据列表。
"""
cities = ["北京", "上海", "南京", "天津", "深圳"]
genders = ["男", "女"]
ages = [i for i in range(1, 101)]
jobs = ["学生", "老师", "社会人员"]
educations = ["小学毕业", "初中毕业", "高中毕业", "高职学历", "大学专科", "大学本科", "硕士学历",
"博士学历", "博士以上"]
data = []
for _ in range(batch_size):
if generated_rows + self.batch_size > self.rows:
current_batch_size = self.rows - generated_rows
if current_batch_size <= 0:
break
else:
current_batch_size = min(self.batch_size, self.rows - generated_rows)
current_row = len(data) + 1
name = self.generate_name()
age = random.choice(ages)
city = random.choice(cities)
gender = random.choice(genders)
job = random.choice(jobs)
email = self.generate_email()
phone_number = self.generate_phone_number()
address = self.generate_address()
education = random.choice(educations)
data.append([
current_row, name, age, city, gender, job, email, phone_number, address, education
])
return data
这段代码定义了一个名为generate_data_batch的方法,用于生成一批次的数据。下面是对代码的详细分析:
-
generate_data_batch(self, batch_size, generated_rows):生成一批次数据的方法。接收两个参数,batch_size表示批次的数据量,generated_rows表示已生成的总行数。 -
定义了几个属性选项的列表,如
cities、genders、ages、jobs和educations等,用于随机选择生成数据的属性值。 -
创建一个空列表
data,用于存储生成的数据。 -
进行
batch_size次循环,每次循环生成一行数据。 -
在循环开始前,判断剩余行数是否小于等于当前批次数据量。若是,则将当前批次数据量调整为剩余行数。
-
获取当前行号
current_row,此处通过len(data) + 1获取。 -
根据相应的方法生成其他属性值,如
name、age、city、gender、job、email、phone_number、address和education。 -
将生成的数据作为一个列表添加到
data列表中。 -
返回生成的数据列表
data。
经过分析,该方法的功能是生成一批次指定数量的数据,并将生成的数据以列表形式返回。生成的数据包括行号、姓名、年龄、城市、性别、职业、邮箱、电话号码、地址和教育程度等信息。
需要注意的是,代码中的self.batch_size应该修改为batch_size,因为方法的参数已经提供了批次的数据量。
-
在循环开始前,通过判断
generated_rows + batch_size是否大于总行数self.rows,来确定当前批次的数据量current_batch_size。如果已生成的总行数和当前批次数据量之和超过了总行数,则将当前批次数据量调整为总行数减去已生成的总行数。 -
在每一次循环中,生成一行数据,并将其添加到
data列表中。 -
生成的一行数据包括以下内容:
current_row:当前行号,从 1 开始,逐行递增。name:通过调用generate_name()方法生成的姓名。age:随机选择一个年龄属性值,从ages列表中选取。city:随机选择一个城市属性值,从cities列表中选取。gender:随机选择一个性别属性值,从genders列表中选取。job:随机选择一个职业属性值,从jobs列表中选取。email:通过调用generate_email()方法生成的邮箱地址。phone_number:通过调用generate_phone_number()方法生成的电话号码。address:通过调用generate_address()方法生成的地址。education:随机选择一个教育程度属性值,从educations列表中选取。
-
循环结束后,返回生成的数据列表
data。
2.8保存数据到Excel
@staticmethod
def save_to_excel(data, file_path):
"""将数据保存到Excel文件中。
Args:
data (list): 要保存的数据列表。
file_path (str): 文件路径。
"""
df = pd.DataFrame(
data,
columns=["编号", "姓名", "年龄", "城市", "性别", "职业", "邮箱", "电话", "地址", "学历"]
)
df.to_excel(file_path, index=False)
这是一个静态方法 save_to_excel,用于将数据保存到 Excel 文件中。下面是对方法的分析:
-
方法的参数有两个:
data是要保存的数据列表,file_path是文件路径。 -
在方法内部,首先使用 pd.DataFrame 创建一个 DataFrame 对象
df。data列表包含了要保存的数据,而columns参数指定了每一列的名称,包括编号、姓名、年龄、城市、性别、职业、邮箱、电话、地址和学历。 -
调用
df.to_excel方法将 DataFrame 对象保存为 Excel 文件。file_path参数指定了文件保存的路径,index=False参数表示不将 DataFrame 的索引写入 Excel 文件。
总结起来,这个静态方法将给定的数据保存到 Excel 文件中,并指定了每一列的列名。你可以传入一个数据列表和一个文件路径,然后调用这个方法来保存数据。
2.9生成数据并保存
def generate_and_save_batch(self, folder_path):
"""生成并保存数据批次。
Args:
folder_path (str): 文件夹路径。
Returns:
str: 生成的Excel文件路径。
"""
if self.rows <= 0:
print("请输入大于0的行数")
return
total_batches = (self.rows - 1) // self.batch_size + 1
file_name = f"data_{time.strftime('%Y%m%d%H%M%S')}.xlsx"
file_path = os.path.join(folder_path, file_name)
with tqdm(total=self.rows, desc=f"数据生成进度:0/{self.rows}") as pbar:
generated_rows = 0
data = []
while generated_rows < self.rows:
current_batch_size = min(self.batch_size, self.rows - generated_rows)
batch_data = self.generate_data_batch(current_batch_size, generated_rows)
generated_rows += current_batch_size
data.extend(batch_data)
self.save_to_excel(data, file_path)
pbar.set_description(f"数据生成进度:{generated_rows}/{self.rows}")
pbar.update(current_batch_size)
time.sleep(0.1)
return file_path
这是一个方法 generate_and_save_batch,用于生成并保存数据批次。下面是对方法的分析:
-
方法的参数有一个:
folder_path是文件夹路径,指定要保存生成的 Excel 文件的文件夹。 -
首先,检查生成数据的行数是否大于0。如果不是,则打印提示信息并返回。
-
计算总共需要生成的批次数
total_batches。通过将行数减1除以每批次的大小,再加上1来计算。这样可以确保即使最后一批数据不足每批次的大小,也会生成。 -
生成文件名
file_name,使用当前时间来为文件名添加时间戳,格式为年月日时分秒,如 "data_20210809123456.xlsx"。 -
构建完整的文件路径
file_path,通过使用os.path.join方法将文件夹路径和文件名连接起来。 -
使用
tqdm创建进度条,并设置总共的数据行数为进度条的总数。描述中显示当前生成进度为 0/总行数。 -
初始化
generated_rows为0,用于记录已生成的数据行数。 -
创建空列表
data,用于存储生成的数据。 -
在 while 循环中,当已生成的数据行数小于总行数时,执行以下步骤:
- 计算当前批次的大小
current_batch_size,为每批次的大小和剩余行数之间的较小值。 - 调用
generate_data_batch方法生成当前批次大小的数据,并将它们存储在batch_data中。 - 将已生成的数据行数增加当前批次的大小
current_batch_size。 - 将当前批次的数据添加到
data列表中。 - 调用
save_to_excel方法将当前的所有数据保存到 Excel 文件中,使用之前构建的文件路径file_path。 - 更新进度条的描述,显示当前生成进度为已生成的数据行数/总行数。
- 更新进度条的进度,增加当前批次的大小。
- 暂停0.1秒,以避免进度条刷新过快。
- 循环结束后,返回生成的 Excel 文件的完整路径
file_path。
综上所述,这个方法用于生成指定行数的数据,并将数据保存到指定文件夹下的 Excel 文件中。方法会根据每批次的大小进行分批生成,并在生成过程中显示进度条。最后返回生成的 Excel 文件的路径。
2.10主程序
if __name__ == "__main__":
rows = int(input("请输入要生成的行数:"))
folder_path = input("请输入文件夹路径:")
try:
if folder_path:
os.makedirs(folder_path, exist_ok=True)
except OSError:
print("创建文件夹失败")
exit(1)
start_time = time.time()
print("\n数据生成进度:")
data_generator = DataGenerator(rows)
generated_file = data_generator.generate_and_save_batch(folder_path)
end_time = time.time()
print(f"\nExcel数据已成功生成并保存到文件:{os.path.abspath(generated_file)}")
print(f"共生成 {rows} 行数据,总耗时:{end_time - start_time:.2f} 秒")
print(f"文件名:{os.path.basename(generated_file)}")
这段代码是一个主程序,执行数据生成和保存的过程,并输出相关信息。下面是对代码的分析:
-
首先判断当前模块是否为主模块,即是否直接运行本文件。通过
if __name__ == "__main__":判断条件来实现。 -
使用
input函数获取用户输入要生成的行数和文件夹路径。 -
在
try-except块中,尝试创建文件夹。如果文件夹路径不为空,则使用os.makedirs方法创建文件夹。exist_ok=True参数表示如果文件夹已存在,则不会引发异常。如果创建文件夹失败,则打印提示信息并退出程序。 -
记录开始时间
start_time,使用time.time()函数获取当前时间。 -
打印提示信息 "数据生成进度:"。
-
创建
DataGenerator实例data_generator,将用户输入的行数作为参数传入。 -
调用
generate_and_save_batch方法生成并保存数据批次,传入文件夹路径作为参数。生成的 Excel 文件的完整路径存储在generated_file中。 -
记录结束时间
end_time,使用time.time()函数获取当前时间。 -
打印生成成功的提示信息,包括生成的 Excel 文件的完整路径、生成的行数和总耗时。
-
打印生成的文件名,使用
os.path.basename函数获取文件路径中的文件名部分。
综上所述,这段代码执行了数据生成和保存的过程,并输出了相应的提示信息,包括生成的 Excel 文件的路径、生成的行数和总耗时。
三、函数和方法分析
3.1DataGenerator
class DataGenerator:
def __init__(self, rows, batch_size=1000):
"""数据生成器类,用于生成指定行数的随机数据。
Args:
rows (int): 要生成的数据行数。
batch_size (int, optional): 每批次生成的数据量,默认为 1000。
"""
self.rows = rows
self.batch_size = batch_size
该类的__init__方法是类的构造函数,用于初始化类的属性。
rows参数表示要生成的数据行数,是一个整数。batch_size参数表示每批次生成的数据量,默认为1000,也是一个整数。
在该方法中,使用self.rows = rows将传入的rows赋值给类的属性self.rows,使用self.batch_size = batch_size将传入的batch_size赋值给类的属性self.batch_size。
该方法没有返回值。
通过初始化方法,可以在创建DataGenerator对象时指定要生成的数据行数和每批次生成的数据量。
在DataGenerator类中,除了 __init__ 方法之外,还定义了以下几个静态方法:
-
generate_name()- 生成随机姓名。
- 返回值为随机生成的姓名字符串。
-
generate_phone_number()- 生成随机手机号码。
- 返回值为随机生成的手机号码字符串。
-
generate_address()- 生成随机地址。
- 返回值为随机生成的地址字符串。
-
generate_email()- 生成随机邮箱。
- 返回值为随机生成的邮箱字符串。
这些静态方法都是独立于类的实例的,可以通过类名直接调用。
另外,DataGenerator类还定义了以下实例方法:
-
generate_data_batch(batch_size, generated_rows)- 生成一批次的数据。
- 参数
batch_size表示批次的数据量,generated_rows表示已生成的总行数。 - 返回值为生成的数据列表。
-
save_to_excel(data, file_path)- 将数据保存到 Excel 文件中。
- 参数
data是要保存的数据列表,file_path是文件路径。 - 该方法将数据转换为
DataFrame格式,并使用pandas库将数据保存到指定的文件路径。
-
generate_and_save_batch(folder_path)- 生成并保存数据批次。
- 参数
folder_path表示文件夹路径。 - 返回值为生成的 Excel 文件路径。
- 该方法根据总行数和批次大小计算需要生成的批次数,并循环生成数据并保存到 Excel 文件中。同时,使用
tqdm库显示数据生成进度条,并在生成过程中更新进度条。
这些方法都是通过类的实例来调用的,其中 generate_and_save_batch 方法将会调用其他方法来生成数据和保存文件。
3.2@staticmethod / generate_name
@staticmethod
def generate_name():
"""生成随机姓名。
Returns:
str: 随机生成的姓名。
"""
first_names = ['赵', '钱', '孙', '李', '周', '吴', '郑', '王', '诸葛', '东方']
last_names = ['舒梅', '莉梦', '素艺', '玲羽', '爽莉', '淑玥', '静洁', '瑶茜', '琴瑶', '洁颖', '岳毅', '龙力',
'胜康', '铭怀', '鑫晖', '奇国', '晨畅', '玮熠', '朔凝', '逸敏']
# 随机选择姓和名
first_name = random.choice(first_names)
max_last_name_length = min(4, 5 - len(first_name))
last_name_length = random.randint(1, max_last_name_length)
last_name = ''.join(random.choice(last_names) for _ in range(last_name_length))
full_name = first_name + last_name
# 随机生成的姓名长度不能超过4个字符
while len(full_name) > 4:
last_name_length -= 1
if last_name_length < 1:
break
last_name = ''.join(random.choice(last_names) for _ in range(last_name_length))
full_name = first_name + last_name
return full_name
这是一个静态方法 generate_name(),用于生成随机姓名。下面对该方法进行详细分析:
-
定义了
first_names和last_names两个列表,分别存储姓和名的候选项。 -
随机选择一个姓(
first_name):- 调用
random.choice()方法从first_names列表中随机选择一个元素作为姓。
- 调用
-
计算可选的名字长度(
max_last_name_length):- 名字长度不能超过4个字符(限制条件:5个字符总长度-姓长度),为了保证名字长度合适,需要计算可选的最大名字长度。
-
随机确定名字长度(
last_name_length):- 利用
random.randint()方法在范围 [1, max_last_name_length] 内生成一个随机整数,表示名字的长度。
- 利用
-
随机选择名字(
last_name):- 使用列表推导式和
random.choice()方法生成指定长度的随机名字。
- 使用列表推导式和
-
组合姓和名为完整的姓名(
full_name)。 -
检查名字长度是否超过4个字符:
- 如果名字长度超过4个字符,则减少名字长度,重新生成名字,直到名字长度不超过4个字符,或者不能再减少名字长度。
-
返回随机生成的姓名(
full_name)。
3.3generate_phone_number
@staticmethod
def generate_phone_number():
"""生成随机手机号码。
Returns:
str: 随机生成的手机号码。
"""
second = random.randint(1, 9)
third = random.randint(1, 9)
suffix = random.randint(10000000, 99999999)
return f"1{second}{third}{suffix}"
这是一个静态方法 generate_phone_number(),用于生成随机手机号码。下面对该方法进行详细分析:
-
随机生成第二位数(
second):- 调用
random.randint()方法生成一个范围在 [1, 9] 内的随机整数,表示手机号码的第二位数。
- 调用
-
随机生成第三位数(
third):- 调用
random.randint()方法生成一个范围在 [1, 9] 内的随机整数,表示手机号码的第三位数。
- 调用
-
随机生成后缀(
suffix):- 调用
random.randint()方法生成一个范围在 [10000000, 99999999] 内的随机整数,表示手机号码的后八位。
- 调用
-
组合各部分数字为完整的手机号码(
"1" + second + third + suffix)。 -
返回随机生成的手机号码。
3.4 generate_address
@staticmethod
def generate_address():
"""生成随机地址。
Returns:
str: 随机生成的地址。
"""
cities = ["北京", "上海", "南京", "天津", "深圳"]
district = random.randint(1, 20)
street = random.randint(1, 1000)
return f"{random.choice(cities)}市{district}区{street}号"
这是一个静态方法 generate_address(),用于生成随机地址。下面对该方法进行详细分析:
-
定义了
cities列表,存储一些城市名字作为地址的候选项。 -
随机选择一个城市(
random.choice(cities)):- 调用
random.choice()方法从cities列表中随机选择一个城市名字作为生成地址的城市。
- 调用
-
随机生成区号(
district):- 调用
random.randint()方法生成一个范围在 [1, 20] 内的随机整数,表示地址的区号。
- 调用
-
随机生成街道号(
street):- 调用
random.randint()方法生成一个范围在 [1, 1000] 内的随机整数,表示地址的街道号。
- 调用
-
组合城市、区号和街道号为完整的地址字符串(
"{random.choice(cities)}市{district}区{street}号")。 -
返回随机生成的地址。
3.5generate_email
@staticmethod
def generate_email():
"""生成随机邮箱。
Returns:
str: 随机生成的邮箱。
"""
domains = ["@qq.com", "@dingtalk.com", "@163.com", "@139.com", "@outlook.com", "@sohu.com", "@aliyun.com"]
username = ''.join(random.choices('abcdefghijklmnopqrstuvwxyz0123456789', k=10))
domain = random.choice(domains)
return f"{username}{domain}"
这是一个静态方法 generate_email(),用于生成随机邮箱。下面对该方法进行详细分析:
-
定义了
domains列表,存储一些常见邮箱域名作为邮箱的候选项。 -
随机生成用户名(
username):- 调用
random.choices()方法从可选字符集合中随机选择10个字符来构建用户名。 - 可选字符集合为小写字母和数字的组合('abcdefghijklmnopqrstuvwxyz0123456789')。
- 使用
''.join()方法将10个字符连接在一起。
- 调用
-
随机选择一个邮箱域名(
random.choice(domains)):- 调用
random.choice()方法从domains列表中随机选择一个邮箱域名作为生成邮箱的域名。
- 调用
-
组合用户名和域名为完整的邮箱地址字符串(
"{username}{domain}")。 -
返回随机生成的邮箱地址。
3.6generate_data_batch
def generate_data_batch(self, batch_size, generated_rows):
"""生成一批次的数据。
Args:
batch_size (int): 批次的数据量。
generated_rows (int): 已生成的总行数。
Returns:
list: 生成的数据列表。
"""
cities = ["北京", "上海", "南京", "天津", "深圳"]
genders = ["男", "女"]
ages = [i for i in range(1, 101)]
jobs = ["学生", "老师", "社会人员"]
educations = ["小学毕业", "初中毕业", "高中毕业", "高职学历", "大学专科", "大学本科", "硕士学历",
"博士学历", "博士以上"]
data = []
for _ in range(batch_size):
if generated_rows + self.batch_size > self.rows:
current_batch_size = self.rows - generated_rows
if current_batch_size <= 0:
break
else:
current_batch_size = min(self.batch_size, self.rows - generated_rows)
current_row = len(data) + 1
name = self.generate_name()
age = random.choice(ages)
city = random.choice(cities)
gender = random.choice(genders)
job = random.choice(jobs)
email = self.generate_email()
phone_number = self.generate_phone_number()
address = self.generate_address()
education = random.choice(educations)
data.append([
current_row, name, age, city, gender, job, email, phone_number, address, education
])
return data
这是一个定义在类中的方法 generate_data_batch(),用于生成一批次的数据。下面对该方法进行详细分析:
-
定义了一些常量列表:
cities:存储了一些城市名作为地址的候选项。genders:存储了两个性别选项("男"和"女")。ages:存储了一个包含从1到100的整数的列表,表示年龄的候选项。jobs:存储了一些职业选项("学生"、"老师"和"社会人员")。educations:存储了一些学历选项。
-
创建一个空的
data列表用于存储生成的数据。 -
使用循环来生成指定数量的数据行:
- 检查是否剩余的可生成行数小于批次的数据量,如果是则将当前批次的大小设为剩余的行数。
- 如果剩余的可生成行数小于等于0,则跳出循环。
- 否则,将当前批次的大小设为当前批次大小与剩余行数中较小的值。
-
生成每一行的数据:
- 计算当前行号(
current_row),通过获取data列表的长度加1得到。 - 调用
self.generate_name()方法生成姓名。 - 从
ages列表中随机选择一个年龄作为生成的年龄。 - 从
cities列表中随机选择一个城市作为生成的城市。 - 从
genders列表中随机选择一个性别作为生成的性别。 - 从
jobs列表中随机选择一个职业作为生成的职业。 - 调用
self.generate_email()方法生成邮箱地址。 - 调用
self.generate_phone_number()方法生成电话号码。 - 调用
self.generate_address()方法生成地址。 - 从
educations列表中随机选择一个学历作为生成的学历。
- 计算当前行号(
-
将当前行的数据以列表的形式添加到
data列表中。 -
返回生成的数据列表。
3.7save_to_excel
@staticmethod
def save_to_excel(data, file_path):
"""将数据保存到Excel文件中。
Args:
data (list): 要保存的数据列表。
file_path (str): 文件路径。
"""
df = pd.DataFrame(
data,
columns=["编号", "姓名", "年龄", "城市", "性别", "职业", "邮箱", "电话", "地址", "学历"]
)
df.to_excel(file_path, index=False)
这是一个定义在类外部的静态方法 save_to_excel(),用于将数据保存到 Excel 文件中。下面对该方法进行详细分析:
-
接收两个参数:
data:要保存的数据列表。file_path:文件的路径,表示保存到哪个 Excel 文件中。
-
使用
pd.DataFrame()函数创建一个 DataFrame 对象df,并传入以下参数:data:要保存的数据列表。columns:指定 DataFrame 的列名,包括 "编号"、"姓名"、"年龄"、"城市"、"性别"、"职业"、"邮箱"、"电话"、"地址" 和 "学历"。
-
调用 DataFrame 对象的
to_excel()方法,将 DataFrame 写入 Excel 文件中。file_path:指定保存的文件路径。index=False:指定不保存行索引。
注意:在使用该静态方法之前,需要确保已经导入了 pandas 库,并且分配给它别名 pd。
3.8generate_and_save_batch
def generate_and_save_batch(self, folder_path):
"""生成并保存数据批次。
Args:
folder_path (str): 文件夹路径。
Returns:
str: 生成的Excel文件路径。
"""
if self.rows <= 0:
print("请输入大于0的行数")
return
total_batches = (self.rows - 1) // self.batch_size + 1
file_name = f"data_{time.strftime('%Y%m%d%H%M%S')}.xlsx"
file_path = os.path.join(folder_path, file_name)
with tqdm(total=self.rows, desc=f"数据生成进度:0/{self.rows}") as pbar:
generated_rows = 0
data = []
while generated_rows < self.rows:
current_batch_size = min(self.batch_size, self.rows - generated_rows)
batch_data = self.generate_data_batch(current_batch_size, generated_rows)
generated_rows += current_batch_size
data.extend(batch_data)
self.save_to_excel(data, file_path)
pbar.set_description(f"数据生成进度:{generated_rows}/{self.rows}")
pbar.update(current_batch_size)
time.sleep(0.1)
return file_path
这段代码定义了一个名为generate_and_save_batch的方法,用于生成并保存数据批次。下面对代码中的函数和方法进行详细分析:
-
def generate_and_save_batch(self, folder_path)::定义了一个方法generate_and_save_batch,接受一个参数folder_path表示文件夹路径。 -
if self.rows <= 0::检查属性self.rows是否小于等于0。如果是,则打印提示信息"请输入大于0的行数",并返回。 -
total_batches = (self.rows - 1) // self.batch_size + 1:计算要生成的数据批次的总数。通过计算(self.rows - 1) // self.batch_size + 1得到,使用整除和加一的方式确保所有的行都被处理。 -
file_name = f"data_{time.strftime('%Y%m%d%H%M%S')}.xlsx":根据当前时间生成一个文件名。文件名格式为"data_年月日时分秒.xlsx",例如"data_20230809065518.xlsx"。 -
file_path = os.path.join(folder_path, file_name):使用os.path.join()方法将文件夹路径folder_path和文件名file_name拼接起来,得到完整的文件路径file_path,表示新生成的Excel文件的路径。 -
with tqdm(total=self.rows, desc=f"数据生成进度:0/{self.rows}") as pbar::使用tqdm创建一个进度条,总共需要处理self.rows个数据,进度条的描述为"数据生成进度:0/总行数"。 -
generated_rows = 0:初始化变量generated_rows为0,表示已生成的行数。 -
data = []:创建一个空列表data,用于存储生成的数据。 -
while generated_rows < self.rows::使用循环生成数据批次,直到生成的行数达到或超过指定的总行数self.rows。 -
current_batch_size = min(self.batch_size, self.rows - generated_rows):计算当前批次的大小。取self.batch_size和剩余行数self.rows - generated_rows中较小的值作为当前批次的大小。 -
batch_data = self.generate_data_batch(current_batch_size, generated_rows):调用self.generate_data_batch()方法生成指定批次大小的数据,并传入已生成的行数generated_rows,返回批次数据batch_data。 -
generated_rows += current_batch_size:将当前批次的大小添加到已生成的行数中。 -
data.extend(batch_data):将批次数据batch_data添加到data列表中。 -
self.save_to_excel(data, file_path):调用self.save_to_excel()方法,将生成的数据保存到Excel文件中。传入数据列表data和文件路径file_path。 -
pbar.set_description(f"数据生成进度:{generated_rows}/{self.rows}"):更新进度条的描述,表示当前已生成的行数和总行数的进度。 -
pbar.update(current_batch_size):更新进度条的进度,增加当前批次的大小。 -
time.sleep(0.1):通过time.sleep(0.1)函数暂停一段时间,以便显示更新的进度条。 -
return file_path:返回生成的Excel文件的路径file_path。
需要注意的是,在使用该方法之前,需要确保已经导入了os、time模块,并且已经定义了generate_data_batch()和save_to_excel()方法。
3.9主程序
if __name__ == "__main__":
rows = int(input("请输入要生成的行数:"))
folder_path = input("请输入文件夹路径:")
try:
if folder_path:
os.makedirs(folder_path, exist_ok=True)
except OSError:
print("创建文件夹失败")
exit(1)
start_time = time.time()
print("\n数据生成进度:")
data_generator = DataGenerator(rows)
generated_file = data_generator.generate_and_save_batch(folder_path)
end_time = time.time()
print(f"\nExcel数据已成功生成并保存到文件:{os.path.abspath(generated_file)}")
print(f"共生成 {rows} 行数据,总耗时:{end_time - start_time:.2f} 秒")
print(f"文件名:{os.path.basename(generated_file)}")
这段代码是一个主程序,用于生成并保存数据批次,并输出相关信息。下面对代码的各部分进行详细分析:
-
if __name__ == "__main__"::主程序的入口,当直接运行该文件时执行以下代码。 -
rows = int(input("请输入要生成的行数:")):通过输入函数获取用户输入的要生成的行数,并将其转换为整数类型赋值给变量rows。 -
folder_path = input("请输入文件夹路径:"):通过输入函数获取用户输入的文件夹路径,并赋值给变量folder_path。 -
try::使用try-except块捕获可能出现的异常。 -
if folder_path::判断用户输入的文件夹路径是否非空。如果非空,则进入下一步;否则跳过创建文件夹的步骤。 -
os.makedirs(folder_path, exist_ok=True):使用os.makedirs()函数创建指定的文件夹路径。参数exist_ok=True表示如果文件夹已存在,则不会引发异常。 -
except OSError::捕获OSError异常,表示创建文件夹时出错。 -
print("创建文件夹失败"):打印提示信息"创建文件夹失败"。 -
exit(1):退出程序,参数1表示以非零状态码退出。 -
start_time = time.time():记录程序开始执行的时间点,使用time.time()函数获取当前时间。 -
print("\n数据生成进度:"):打印提示信息"数据生成进度:",表示接下来会输出数据生成的进度。 -
data_generator = DataGenerator(rows):实例化一个DataGenerator对象data_generator,将用户输入的行数rows作为参数传递给构造函数。 -
generated_file = data_generator.generate_and_save_batch(folder_path):调用data_generator对象的generate_and_save_batch()方法,生成并保存数据批次。将返回的生成的Excel文件的路径赋值给变量generated_file。 -
end_time = time.time():记录程序执行结束的时间点,使用time.time()函数获取当前时间。 -
print(f"\nExcel数据已成功生成并保存到文件:{os.path.abspath(generated_file)}"):打印提示信息,表示Excel数据已经成功生成并保存到文件,输出生成的文件的绝对路径。 -
print(f"共生成 {rows} 行数据,总耗时:{end_time - start_time:.2f} 秒"):打印提示信息,表示一共生成了多少行数据,并输出程序执行的总耗时,保留小数点后两位。 -
print(f"文件名:{os.path.basename(generated_file)}"):打印提示信息,表示生成的文件的文件名,通过os.path.basename()函数获取。
该主程序首先获取用户输入的行数和文件夹路径,然后根据用户的输入进行相应的处理,最后输出生成数据的相关信息。
四、整体分析
- 代码能做什么?
这段Python代码可以生成指定行数的随机数据并将其保存为Excel文件。
- 代码实现的逻辑是什么?
首先,定义了一个名为DataGenerator的类,该类包含了多个方法,可以生成随机的姓名、手机号码、地址、邮箱等数据,以及生成一批次数据和将数据保存到Excel文件中的方法。
在生成数据的过程中,使用了Python内置的random模块和choices()函数,可以随机选择姓名的姓氏和名字、手机号码的前三位、地址中的城市、性别、职业、邮箱等信息。同时,为了避免生成的姓名过长,代码中限制了姓名长度不超过4个字符。
对于生成一批次数据的方法generate_data_batch(),输入参数包括批次数据的数量和已生成的总行数,输出结果为生成的数据列表。在该方法中,使用了Python内置的列表推导式,将生成的数据添加到列表中。
在数据生成完成之后,调用了save_to_excel()方法将数据保存为Excel文件。在该方法中,使用了Pandas库中的DataFrame对象和to_excel()方法,将数据存储到Excel文件中。
主函数中,首先通过输入命令行参数获取要生成的数据行数和Excel文件保存的路径,创建一个DataGenerator对象,并调用generate_and_save_batch()方法生成并保存数据。同时,使用tqdm库可以显示生成数据的进度条。
3.涉及到IO流相关的操作?
该代码涉及到了IO流的相关操作。在save_to_excel()方法中,将生成的数据写入Excel文件中,需要使用文件IO流的相关方法。同时,在主函数中,需要获取用户输入的Excel文件保存路径,并根据该路径创建文件夹,也需要使用文件IO流的相关方法。
- 其他方面的代码分析。
该代码中使用了Python的多个标准库和第三方库,如os、random、time、pandas和tqdm等,这些库能够实现各种常见的操作和功能。同时,代码还利用了Python的面向对象编程能力,通过类的封装实现了数据生成和Excel文件保存的功能。代码的可读性较好,使用了较多的注释和命名规范,便于其他开发者理解和维护代码。
五、代码维护和更新
5.1 需要增加列或者其他信息
如果您需要增加列或者其他信息,可以按照以下步骤进行:
-
修改
DataGenerator类中的属性:如果您需要增加列,可以在DataGenerator类中添加新的属性,例如job_title、company等。如果您需要修改已有属性,可以直接修改DataGenerator类中相应的属性。 -
修改生成数据方法:如果您需要生成新的数据,可以在
DataGenerator类中添加新的生成数据方法,例如generate_job_title()、generate_company()等。在这些方法中使用Python内置的random模块和choices()函数生成随机数据。 -
修改Excel文件保存方法:如果您需要将新的数据保存到Excel文件中,可以在
DataGenerator类中修改save_to_excel()方法。在该方法中,您需要调整Pandas库中的DataFrame对象和to_excel()方法,将新的数据写入Excel文件中。 -
修改主函数:如果您需要生成新的数据并保存到Excel文件中,可以在主函数中调用新的生成数据方法和Excel文件保存方法。同时,需要修改命令行参数的解析方式,例如增加新的参数。
总之,如果您需要向代码中增加新的功能,需要在DataGenerator类中添加新的属性和方法,同时修改Excel文件保存方法和主函数。需要注意的是,修改代码时需要确保代码的兼容性和稳定性。
5.2确保代码的兼容性和稳定性
当您向代码中添加新的信息或者修改已有信息时,需要确保代码的兼容性和稳定性。以下是具体的步骤:
-
首先,您需要在
DataGenerator类中添加新的属性,例如job_title、company等。同时,如果您需要修改已有属性,需要确保修改不会影响原有的代码和功能。 -
然后,您需要修改生成数据方法,添加新的生成数据方法,例如
generate_job_title()、generate_company()等。在这些方法中使用Python内置的random模块和choices()函数生成随机数据,并将新的数据添加到数据生成列表中。 -
接下来,您需要修改Excel文件保存方法,将新的数据写入Excel文件中。在该方法中,需要调整Pandas库中的DataFrame对象和to_excel()方法,以便将新的数据写入Excel文件中。
-
最后,您需要修改主函数,调用新的生成数据方法和Excel文件保存方法。如果您需要增加新的参数,需要修改命令行参数的解析方式,例如使用Python内置的
argparse模块等。
在修改代码的过程中,需要进行测试和验证,确保代码的兼容性和稳定性。可以使用单元测试和集成测试等测试方法,以便发现和解决代码中的问题。同时,需要及时更新代码注释和文档,以便其他开发人员更好地理解代码。
5.3示例演示
假设您需要添加职位、公司等字段,那么您需要按照以下步骤进行修改:
- 在
DataGenerator类中添加新的属性job_title和company:
class DataGenerator:
def __init__(self):
self.first_names = ['John', 'Jane', 'Michael', 'Emily', 'William', 'Sophia']
self.last_names = ['Smith', 'Johnson', 'Brown', 'Lee', 'Taylor', 'Davis']
self.cities = ['New York', 'Los Angeles', 'Chicago', 'Houston', 'Phoenix', 'Philadelphia']
self.genders = ['Male', 'Female']
self.education = ['Associate Degree', 'Bachelor’s Degree', 'Master’s Degree', 'PhD']
self.email_domains = ['gmail.com', 'yahoo.com', 'hotmail.com', 'outlook.com']
self.phone_number_prefixes = ['800', '888', '877', '866', '855', '844', '833']
self.addresses = ['123 Main St', '456 Elm St', '789 Oak St', '12 Pine St', '345 Maple St']
self.job_title = ['Software Engineer', 'Data Analyst', 'Product Manager', 'Marketing Specialist']
self.company = ['Google', 'Amazon', 'Microsoft', 'Apple']
- 在
DataGenerator类中添加新的生成数据方法generate_job_title()和generate_company():
class DataGenerator:
def __init__(self):
# ...
def generate_job_title(self):
return random.choice(self.job_title)
def generate_company(self):
return random.choice(self.company)
- 在
DataGenerator类中的方法generate_data()中,添加职位和公司字段:
class DataGenerator:
def __init__(self):
# ...
def generate_data(self, num_rows):
data = []
for i in range(num_rows):
first_name = self.generate_first_name()
last_name = self.generate_last_name()
city = self.generate_city()
gender = self.generate_gender()
education = self.generate_education()
email = self.generate_email(first_name, last_name)
phone_number = self.generate_phone_number()
address = self.generate_address()
job_title = self.generate_job_title()
company = self.generate_company()
row = [first_name, last_name, city, gender, education, email, phone_number, address, job_title, company]
data.append(row)
return data
- 在
DataGenerator类中修改Excel文件保存方法save_to_excel(),将新的数据写入Excel文件中:
class DataGenerator:
def __init__(self):
# ...
def save_to_excel(self, data, file_path):
df = pd.DataFrame(data, columns=['First Name', 'Last Name', 'City', 'Gender', 'Education', 'Email', 'Phone Number', 'Address', 'Job Title', 'Company'])
df.to_excel(file_path, index=False)
- 在主函数中调用新的生成数据方法
generate_job_title()和generate_company(),并且修改命令行参数的解析方式:
def main():
parser = argparse.ArgumentParser(description='Generate random data and save to Excel file')
parser.add_argument('num_rows', type=int, help='Number of rows to generate')
parser.add_argument('file_path', type=str, help='File path to save Excel file')
args = parser.parse_args()
data_generator = DataGenerator()
data = data_generator.generate_data(args.num_rows)
data_generator.save_to_excel(data, args.file_path)
通过以上步骤,您就可以完成新增职位和公司字段的功能,同时保证了代码的兼容性和稳定性。
浙公网安备 33010602011771号