数据类型实战实例
字符串格式问题
示例1:存在一个变量number =1,如果需要输出格式“001”如果实现?
print(“%03d”%number)
%d 替换的是number的值,03d表示的输出3位数值型,如果真实数值型,如果真实数值只有1位,则会在在高位自动补0输出,所以结果得到001
# 利用百分号进行占位格式化输出
print("%03d"%1)
001
Process finished with exit code 0
示例2:存在一个变量number1 =1.22222,,如果需要保留两位小数应该如何实现
print(“%.2f”%number1)
小数的格式化输出需要使用%f,保留两位小数格式.2f
print("%.2f"%1.2)
示例3:存在一个变量number2 =,如果要输出"%d1"如何实现?
print(“%%d%d”%number2)
在字符串格式化中%d表示整型占位符,如果需要以整型字符串的形式输出,则需要在%d的前面添加%进行转义,所以第一个%d表示输出的是字符串,第二个%d是number2的占位,最前面的%是进行转义
print("%%d%d"%1)
字符串驻留机制问题
在python中会出现字符串驻留(intern)的情况,即在某些情况下尝试使用现有的不可变对象,而不是每次都去创建一个新的对象,这些驻留的对象在内部使用类似与字典的结构(驻留池)进行驻留,驻留后,许多变量可能指向内存中的相同字符串对象,从而节省内存
1、基本原理
系统会维护一个interned字典类型用于记录已经被驻留的字符串对象。在使用过程中,如果字符串a需要驻留,那么会在interned字典类型中检测其是否存在,若存在则指向存在的字符串对象,a的引用计数减1;若不存在,则记录a到interned字典中
2、字符串驻留实例
(1)字符串编译时驻留,非运行时不驻留
在代码中,print(str2 + str3)会输出’woodprogramming’,因为使用+运算符将str2和str3拼接在一起生成了一个新的字符串对象。
而print(str2 + str3 is “woodprogramming”)返回的是False。这是因为is运算符比较的是两个对象的身份标识(即在内存中的地址),而不只是比较字符串的值是否相等。
在Python中,长字符串对象的驻留优化不一定会发生,因此str2 + str3生成的新字符串对象可能与字符串常量"woodprogramming"的地址不同。尽管这两个字符串的值相等,但它们并不是同一个对象,所以is运算符返回的结果是False
str1 = "wood" + "programming"
print(str1 is "woodprogramming") # true
# 在python中过对于较短的字符串,解释器会为他们分配相同的内存空间
# 对于字符串"wood"和"programming",它们都是较短的字符串。当我们使用"+"运算符将它们连接起来形成str1时,
# 解释器可能会对结果字符串"woodprogramming"进行驻留优化,这意味着两个字符串在内存中引用的地址是相同的
# 当我们使用"is"运算符比较str1和"woodprogramming"时,由于驻留优化,它们在内存中引用的地址相同,所以返回True
str2 = "wood"
str3 = "programming"
print(str2+str3)
print(str2 +str3 is "woodprogramming") # FALSE 不同的内存空间
(2)如果字符串长度等于0或者1,则默认驻留
(3)如果字符串长度大于1,且只包含字母数字、下划线时,则默认实现驻留
在Python中,短字符串对象的驻留优化可能会发生,这通常适用于包含少量字符的字符串
(4)字符串由intern模块指定驻留
from sys import intern
str1 =intern("wood!@")
str2 =intern("wood!@")
print(str1 is str2)
返回true,通过调用了intern模块的intern方法完成了字符串的驻留
字典减值对互换
字典是python常用的数据结构,用于存放具有映射关系的数据
定义语法:变量名 = {key1:value1,key2:value2,…}
1、键名定义要求
键名必须是可哈希的类型(元组,字符串,数值型,。。。’),不可哈希的类型(如列表、字典)无法定义,实际上也是对应着可变对象(不可哈希)和不可变对象(可哈希)
(1)可变对象:list,dict,set
(2)不可变对象:truple,string,int,float,bool
2、键名重名问题
在声明或者更新字典时,如果键名重复,则后续的键值对会覆盖前面的键值对
dict1 = {"username":"zhangsan","passwd":"123456","username":"lisi"}
print(dict1)
后面同名的键值对lisi会替换掉前面的zhangsan
3、字典键值对互换问题
存在一个字典dict1 ={“username”:“zhangsan”,“passwd”:“123456”} 可以使用代码变为;
{“zhangsan”:“username”,“123456”:“passwd”}
使用字典推导式(dictionary comprehension)将dict1中的键值对进行键值互换,生成一个新的字典
{value:key for key,value in dict1.items()}表示对于dict1中的每个键值对,将其值作为新字典中的键,将其键作为新字典中的值。这样就创建了一个新字典,其中原字典的值成为了新字典的键,原字典的键成为了新字典的值
dict1 = {"username":"zhangsan","passwd":"123456"}
new_dict1 = {value:key for key,value in dict1.items()}
print(new_dict1)
将一个数据序列结构构建成另一个新的数据序列结构的过程称为推导式,又可以叫解析式
(1)列表(list)推导式 [expression(i) for i in old_list if condition(i)]
例:过滤提取列表中的偶数
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
evens = [x for x in numbers if x % 2 == 0]
print(evens)
(2)字典(dict)推导式
例:创建一个包含键为字符串,值为其首字母的字典
words = ["apple", "banana", "orange"]
first_letters = {word: word[0] for word in words}
print(first_letters)
(3)集合(set)推导式
例:从字符串列表中提取单词的长度,生成一个长度集合
words = ["apple", "banana", "orange", "kiwi", "grapefruit"]
lengths = {len(word) for word in words}
print(lengths)
使用字典表示字符串统计结果
str2 = "wood programming is the best education"
result = {}
for i in str2:
result[i] = str2.count(i)
print(result)
利用一个空字典接收取出来的值,在进行统计
循环逻辑实战实例
九九乘法表的四种形式
1、左下角九九乘法表
for row in range(1,10): # 控制行
for col in range(1,row+1): # 控制列
print("%d*%d=%d"%(col,row,col*row),end="\t")
print("") # 利用end的特性,进行换行输出
2、左上角九九乘法表
for row in range(9,0,-1): # 控制行,使用倒叙循环
for col in range(1,row+1): # 控制列
print("%d*%d=%d"%(col,row,col*row),end="\t")
print("")
3、右上角九九乘法表
for row in range(9,0,-1): # 控制行,使用倒叙循环
for space in range(9-row):
print("\t",end="\t")
for col in range(row,0,-1):
print("%d*%d=%d"%(col,row,col*row),end="\t")
print("")
4、右下角九九乘法表
for row in range(1,10):
for space in range(9-row):
print("\t",end="\t")
for col in range(row,0,-1):
print("%d*%d=%d"%(col,row,col*row),end="\t")
print()
猜数游戏
# Description:#练习:猜数游戏:要求冲入金额,1元=3次 要求输入的是整数金额,小数直接取整(3.5)
# #要求每次都是随机出的新的数,猜对一次得1元,余额如果没有钱则提示是否充值还是退出游戏;
# #玩的每一次都可以选择退出,退出要退钱,退钱规则是根据次数,不满3次的不退钱 7次---->2元
# #要求使用面向对象编程完成此题定义类、方法、属性完成
#-------------------------------------------------------------------------------
#分析:该游戏可以充值:定义一个充值的方法(完成充值的规则)、猜数:计算机所产生的随机数(每次)、用户猜的数
#菜单提示部分:因为每次游戏过程中都需要提示是否退出还是继续玩.....
#首页菜单提示:欢迎来到猜数游戏、1.充值进入游戏 2.退出 进入游戏后的每次提示:1.充值 2.查询 3.退出(返回钱)
#如果游戏次数不足时:1.充值 2.退出(欢迎下次光临)
#退钱部分:退钱规则的实现
#属性:金额 次数----->可以根据金额进行获取
import random
class Game:
def index_tip(self):
print("*************欢迎来到猜数游戏***************")
#进入首次游戏的时候的菜单提示
def index_page(self):
print("1.充值进入游戏\n2.退出")
get_choice=input("请输入您的选择:")
if get_choice=="1":
#完成充值
print("恭喜您,充值成功,当前次数余额%d"%self.change_count())
self.access_game_page()
elif get_choice=="2":
self.exit_game()
else:
print("当前输入错误,请重新输入选项")
self.index_page()
#创建对象初始
def __init__(self):
self.index_tip()
self.index_page()
#定义进入游戏的菜单:
def access_game_page(self):
if self.count>0:
print("1.充值\n2.进入游戏\n3.退出")
get_step=input("请选择下一步操作")
if get_step=="1":
#该金额需要累加
self.count+=self.change_count()
print("总次数是:%d"%self.count)
self.access_game_page()
elif get_step=="2":
self.compare_value()
elif get_step=="3":
self.exit_game_money()
else:
print("请选择正确的操作步骤")
self.access_game_page()
else:
print("当前次数为0,请充值后进入游戏!")
self.index_page()
#声明一个退出的方法
def exit_game_money(self):
print("返回金额:%d元"%(self.count//3))
self.exit_game()
#定义玩游戏的规则:
#定义玩家
def compare_value(self):
get_computer_value=self.get_computer_value()
print("计算机的数:%d"%get_computer_value)
get_paly=int(input("请输入猜的数:"))
if get_paly==get_computer_value:
self.compare_right()
else:
self.compare_error()
def compare_right(self):
print("恭喜您猜对")
self.count += 2
print("当前游戏的总次数:%d" % self.count)
self.access_game_page()
#如果猜错的方法实现
def compare_error(self):
self.count-=1
print("很遗憾,猜错了,继续努力!")
print("剩余总次数:%d"%self.count)
self.access_game_page()
#定义计算机---->计算机随机产生的数(定义数的范围,根据猜数的范围进行)
def get_computer_value(self):
dict1={"简单":(1,10),"普通":(1,100),"困难":(1,1000)}
get_mode=input("请选择游戏模式:1.简单\n2.普通\n3.困难")
if get_mode=="1":
print("当前模式为简单模式,范围:1-10")
return random.randint(dict1["简单"][0],dict1["简单"][1])
elif get_mode=="2":
print("当前模式为普通模式,范围:1-100")
return random.randint(dict1["普通"][0], dict1["普通"][1])
elif get_mode=="3":
print("当前模式为困难模式,范围:1-1000")
return random.randint(dict1["困难"][0], dict1["困难"][1])
else:
print("请选择正确的模式!")
return self.get_computer_value()
#定义一个方法:将金额转换成完的次数 1元=3次
def change_count(self):
self.charge_type()
self.count=self.get_charge*3
return self.count
#设计一个充值的方法;只是用于判定输入充值的类型
def charge_type(self):
self.get_charge=input("请输入充值的金额:")
try:
self.get_charge=int(self.get_charge)
self.charge_fushu(self.get_charge)
except:
try:
self.get_charge=int(float(self.get_charge))
self.charge_fushu(self.get_charge)
except:
print("请输入整型或者浮点型")
self.charge_type()
#定义一个判定金额是否为负数
def charge_fushu(self,get_charge):
if get_charge<=0:
print("请输入正确的金额")
self.charge_type()
#退出游戏(没有计算退钱的)
def exit_game(self):
print("欢迎下次光临!")
if __name__ == '__main__':
g=Game()
迭代器、生成器实战实例
字符串、列表、元组。可以通过索引进行循环取出其所包含的元素,但是某些数据类型中不存在索引结构,如文件、集合、字典等,如果想从这些类型中取出对应的元素,则必须找出一种不依赖于索引的迭代方式,即迭代器
如果存在某种数据结构即可以存储列表元素,又可以依次推算提取元素,这样就不必创建完整的list,在python中,这种既可以循环遍历又可以计算的机制就是生成器
1、阅读以下代码,给出执行后的结果
def test1():
for i in range(4):
yield i
g = test1()
g1 = (i for i in g)
g2 = (i for i in g1)
g3 = (i for i in list(g1))
print(list(g1))
print(list(g2))
输出结果为:
代码由上到下执行
1、首先调用test函数。g的值是0,1,2,3
2、g1通过迭代生成器取的g中的值,g1为0,1,2,3
3、g2也是通过迭代生成器在g1中进行取值
因为print(list(g1))已经将生成器中的g1的元素全部都取完了,所以此时g2生成器遍历g1生成器的结果就是空值
g3对象也是通过一个生成器推导式声明的生成器对象,且直接引用了list(g1),说明已经将g1的值全部取完,根据生成器取值只能取一次的规则,可以得g2取的是g1的空对象,此时所有的元素都在g3生成器中,g1生成器是空,g2生成器通过g1生成器取值后也是空值,所以两个输出都是空列表
2、阅读下面代码,分析过程
def add(n,i):
return n+i
def test():
for i in range(4):
yield i
g = test()
for n in [1,10,15]:
g =((add,i) for i in g)
print(list(g))
首先,g是一个生成器对象,在调用test函数后其值为【0,1,2,3】,然后进入for循环,在for循环中:
当n =1时,g = (add(n,i) for i in g)
当n = 10 时,g = (add(n,i) for i add(n,i) for i in g)
当n =5时, g = (add(n,i) for i in (add(n,i) for i in (add(n,i) for i in g)
因为最后才开始计算,所以n = 5时才开始调用生成器g
最后的结果为g= [15,16,17,18]
使用匿名韩式完成九九乘法表
匿名函数不需要用def关键字进行定义,也不需要声明其函数名,语法:
lambda [arg1[arg2,…argn]:expression
中括号参数可选,如果声明了变量,name在参数的表达式中也要体现出来
multipcation_table = lambda : '\n'.join("".join(['%2d*%2d = %2d'%(col,row,col*row)
for col in range(1,row+1)]) for row in range(1,10))
print(multipcation_table())
该段代码使用了匿名函数、列表推导式、循环嵌套、字符串拼接、rang函数等知识点
声明的匿名函数即使没有参数,在调用时也必须加小括号,如果没有加小括号,输出的时候讲述匿名函数的对象
装饰器实战实例
时间计时器装饰器
python中的装饰器其实就是一个函数,调用方式就是使用语法糖@符号,可以应用在类、方法、函数上。如果被装饰的方法或者函数存在参数,则需要通过装饰器的内层函数将参数进行传递;被装饰的函数调用时是否存在返回值,取决于内层函数是否将值镜像返回,如果装饰器需要传入参数,则需要考虑三层函数,此时第二层函数固定传入被装饰函数的对象;第一层函数传入的参数即为装饰器中所传入的参数
装饰器主要分为系统装饰器和自定义装饰器。对于系统装饰器而言,后面接触最多的是@classmethod类装饰器和@staticmethod(静态方法装饰器)
@classmethod表示如果需要获取一个类中的属性或方法,除了通过创建对象调用类的属性和方法,还可以通过类名直接调用其属性和方法,但是此属性必须是类属性,不能够调用对象属性;方法必须是通过@classmethod进行装饰的,不能够调用对象方法。装饰的方法的第一个参数,参数名通常是cls,与self的使用相同,但是意义不同,self表示传入new产生的对象,而cls表示传入当前的类
注意:类只能够调用类属性和类方法,不能够调用对象属性和对象方法;但是对象实例既可以调用类属性、类方法,又可以调用对象属性,对象方法
@staticmethod表示静态方法。该方法不需要传递人和参数,既可以通过类进行调用,也可以通过对象进行调用;只能够调用类属和类方法,不能调用实例方法(要调用,必须创建对象调用,这样与后续创建的对象无关联);并且表示所有的对象和类都是共享同一份静态属性和方法
装饰器的属性
实质:是一个函数
参数:需要装饰的函数名(并非函数调用)
返回:装饰完的函数名(也并非函数调用)
作用:在原有函数实现功能基础上不改变其任何操作,可实现额外的功能扩展
特点:基于现有的对象不需要做任何代码上的变动
应用场景:如插入日志、性能测试、事务处理、权限校验等
需求:在不改变其代码的情况下,完成检测任意一段代码的执行时间
分析:先定义一个timer装饰器,然后将该装饰器装饰在需要检测代码运行时间的程序块上
定义一个timer装饰器
import time
# 装饰器timer,其中function为要装饰的函数
def timer(function):
def wrapper():
time_start =time.time()
function()
time_end = time.time()
spend_time = time_end - time_start
print(f"花费的时间是{spend_time}秒")
return wrapper
第二步,对get_sum函数进行装饰器的添加,@timer引用timer装饰器函数
@timer
def get_sum():
sum = 0
for i in range(1,100001):
sum +=i
print(f"1-100000累计和{sum}")
if __name__ == '__main__':
get_sum()
输出结果:
声明了timer装饰器后,任何一个需要检测程序代码执行时间的程序,都可以直接使用@timer装饰器装饰函数,然后被装饰的函数运行后也将或得运行时间,及功能额外实现了扩展
自定义装饰器
自定义类装饰器
class Decorator(object):
def __init__(self,func_name):
self.func_name = func_name
def __call__(self):
print("decorator start")
self.func_name()
print("decrator end")
调用类函数器,将该类装饰器装饰在一个函数上
@Decorator
def func():
print("func")
if __name__ == '__main__':
func()
输出结果:
@Decorator装饰在func函数上实际等价于调用
p = Decorator(func)
p()
代码执行过程中,首先p是类Decorator的一个实例,实现了_call_()方法后,p可以直接被调用,然后传入的参数func就是被装饰在func函数的函数对象,所以会先输出decorator start然后调用func函数执行,最后输出decorator end
注意:_call _()是一个特殊方法,他可以将一个实例变成一个可调用对象,要使用类装饰器,必须实现类中的_call _()方法,就相当于将实例变成了一个方法
面向对象实战实例
面向对象之石头剪刀布游戏
import random
class Game_2(object):
def __init__(self):
self.guess_list = ["石头","剪刀","布"]
# 将赢的组合规则通过元组进行设定
self.win_combination = [["布","石头"],["石头","剪刀"],["剪刀","布"]]
def play(self):
while True:
computer = random.choice(self.guess_list) # 计算机随机生成一个手势
people = input("请输入:石头,剪刀,布:\n").strip() # 定义玩家输入一个手势
if people not in self.guess_list:
print("请输入正确的手势。。。")
continue
elif computer == people:
print("平手,再玩一次")
elif [computer,people] in self.win_combination:
print("计算机获胜,游戏继续,直到玩家胜利才能退出")
else:
print("玩家获胜!")
break
if __name__ == '__main__':
game = Game_2()
game.play()
提高良好的用户操作,在当前类中添加一个用于控制用户是否继续玩的操作方法
import random
class Game_2(object):
def __init__(self):
self.guess_list = ["石头","剪刀","布"]
# 将赢的组合规则通过元组进行设定
self.win_combination = [["布","石头"],["石头","剪刀"],["剪刀","布"]]
# 声明一个标识符,记录是否继续游戏
self.flag = True
# 声明一个方法,可以实现玩家选择退出游戏还是继续游戏
def chioce(self):
get_chioce = input("是否继续游戏?Y/N")
if get_chioce =="Y":
self.play()
elif get_chioce == "N":
self.flag =False
def play(self):
while True:
if self.flag:
computer = random.choice(self.guess_list) # 计算机随机生成一个手势
people = input("请输入:石头,剪刀,布:\n").strip() # 定义玩家输入一个手势
if people not in self.guess_list:
print("请输入正确的手势。。。")
continue
elif computer == people:
print("平手,再玩一次")
elif [computer,people] in self.win_combination:
print("计算机获胜,游戏继续,直到玩家胜利才能退出")
else:
print("玩家获胜!")
self.chioce()
else:
break
if __name__ == '__main__':
game = Game_2()
game.play()
print("游戏结束,欢迎下次再来")
注意:flag是一个bool类型的变量,bool类型只有两个成员true和false
面向对象之双色球的实现
import random
def random_ball():
one_group = []
while True:
red_ball =random.randint(1,33) # 随机产生一个红球
if red_ball in one_group:
continue # 跳过本次循环
one_group.append(red_ball)
if len(one_group) == 6:
break
one_group.sort()
blue_ball = random.randint(1,16) # 随机产生一个蓝球
# s = ""
# for i in one_group:
# s = s+"%02d"%i
# print(s + "+"+ " %02d" %blue_ball) # 此种情况,数字之间没有空格
ball_str = " ".join("%02d" % num for num in one_group) # 使用空格连接数字的字符串表示形式
print(ball_str + " +" + "%02d" % blue_ball)
if __name__ == '__main__':
random_ball()
下面通过类定义,将红球的获取、蓝球的获取、双色球格式的显示分别声明为三个方法,便于后期调用
import random
class Random_Ball(object):
# 红球获取
def red_ball_l(self):
list = range(1,34)
redball = random.sample(list,6)
redball.sort()
return redball
# 蓝球获取
def blue_ball(self):
return random.randint(1,16)
# 双色球的显示
def random_ball_l(self):
# s = " "
# for i in self.red_ball_l():
# s = s +"%02d"%i
# return s + "+ " + "%02d" % self.blue_ball()
red_balls = self.red_ball_l()
blue_ball = self.blue_ball()
red_balls_str = " ".join("%02d" % num for num in red_balls) # 使用空格连接红球号码的字符串表示形式
return red_balls_str + " + " + "%02d" % blue_ball
if __name__ == '__main__':
random_obj = Random_Ball()
print(random_obj.random_ball_l())
多线程、多进程实战实例
进程是资源分配的最小单位,线程是cpu调度的最小单位
一万条数据在格式文件中的读写操作
完成数据结构设计
import random
import string
class CreateData(object):
# 随机生成一万条数据:姓名随机,要求6-12位
# 可以从数字、字母、符号等内容中随机取值,还可以在网络上取值
# python自带一个string模块,该模块可以获取对应的字符串
def get_name(self):
str_char = ""
# 随机取值的容器,数字、大小写、符号
get_char = string.ascii_letters + string.digits # +string.punctuation
# 定义随机6-12位数字
get_len = random.randint(6, 12)
for i in range(1, get_len + 1):
str_char += random.choice(get_char)
return str_char
# 获取性别
def get_sex(self):
return random.choice(["男", "女"])
# 获取年龄
def get_age(self):
return random.randint(18, 100)
# 获取邮件
def get_email(self):
return self.get_name() + random.choice(["@163.com", "@qq.com"])
# 声明一个方法,可以使一条数据放在一个列表里
def get_one_data(self):
return [self.get_name(), self.get_sex(), self.get_sex(), self.get_age()]
# 测试代码
if __name__ == '__main__':
data = CreateData()
print("随机得到的姓名是:", data.get_name())
print("随机得到性别是:", data.get_sex())
print("随机得到的年龄是:", data.get_age())
print("随机得到的邮箱是:", data.get_email())
运行结果;
因为在创建右键数据时,重新调用了一次获取姓名的方法,此时会重新随机生成一个新的名字,所以无法与刚开始生成的姓名一致,此时邮件中的姓名应该从获取姓名的方法中进行获取
具体操作:
可以在createdata类中声明一个方法,该方法存在一个name属性,初始值为None,然后在get_name方法中将随机生成的str_char变量的值赋给name属性,最后在get_email方法中不调用get_name方法,直接调用self,name属性即可
import random
import string
class CreateData(object):
# 随机生成一万条数据:姓名随机,要求6-12位
# 可以从数字、字母、符号等内容中随机取值,还可以在网络上取值
# python自带一个string模块,该模块可以获取对应的字符串
def __init__(self):
self.name = None
def get_name(self):
str_char = ""
# 随机取值的容器,数字、大小写、符号
get_char = string.ascii_letters + string.digits # +string.punctuation
# 定义随机6-12位数字
get_len = random.randint(6, 12)
for i in range(1, get_len + 1):
str_char += random.choice(get_char)
self.name = str_char # 将随机生成的姓名保存到属性中
return str_char
# 获取性别
def get_sex(self):
return random.choice(["男", "女"])
# 获取年龄
def get_age(self):
return random.randint(18, 100)
# 获取邮件
def get_email(self):
return self.name + random.choice(["@163.com", "@qq.com"]) # 使用保存的姓名属性生成邮件地址
# 声明一个方法,可以使一条数据放在一个列表里
def get_one_data(self):
return [self.get_name(), self.get_sex(), self.get_sex(), self.get_age()]
# 测试代码
if __name__ == '__main__':
data = CreateData()
print("随机得到的姓名是:", data.get_name())
print("随机得到性别是:", data.get_sex())
print("随机得到的年龄是:", data.get_age())
print("随机得到的邮箱是:", data.get_email())
数据生成之后,可以将数据写入指定的格式文件,如excel,csv,json,yaml,xml等
python中openpyxl模块实际存在append方法,将整条记录写入一行,append方法传入的参数是可迭代对象,所以可以将前面随机生成的各个数据设置成一个列表,表示一条记录
def get_one_data(self):
return [self.get_name(), self.get_sex(), self.get_sex(), self.get_age()]
最后通过操作excel模块调用上面生成一条记录的方法即可以完成一万条数据的写入操作
from openpyxl import Workbook
from test01 import CreateData
class ExcelData(object):
def __init__(self):
self.data = CreateData()
self.workbook = Workbook()
self.get_sheet =self.workbook.active
def create_data(self):
for row in range(1,101):
self.get_sheet.append(self.data.get_one_data())
self.workbook.save("data.xlsx")
# 测试代码
if __name__ == '__main__':
excel = ExcelData()
excel.create_data()
一百万条数据在数据库中的插入操作
循环调用实现
import random
import string
import mysql.connector
class InsertData(object):
def __init__(self):
self.conn = None
self.cursor = None
# 连接到MySQL数据库
def connect_to_database(self):
self.conn = mysql.connector.connect(
host='localhost',
user='your_username',
password='your_password',
database='your_database_name'
)
self.cursor = self.conn.cursor()
# 关闭数据库连接
def close_connection(self):
self.cursor.close()
self.conn.close()
# 生成随机姓名
def get_name(self):
str_char = ""
get_char = string.ascii_letters + string.digits
get_len = random.randint(6, 12)
for i in range(1, get_len + 1):
str_char += random.choice(get_char)
return str_char
# 获取性别
def get_sex(self):
return random.choice(["男", "女"])
# 获取年龄
def get_age(self):
return random.randint(18, 100)
# 生成并插入一条数据
def insert_one_data(self):
name = self.get_name()
sex = self.get_sex()
age = self.get_age()
sql = "INSERT INTO your_table_name (name, sex, age) VALUES (%s, %s, %s)"
val = (name, sex, age)
self.cursor.execute(sql, val)
self.conn.commit()
# 批量插入数据
def insert_data(self, num):
for _ in range(num):
self.insert_one_data()
# 测试代码
if __name__ == '__main__':
data = InsertData()
data.connect_to_database()
data.insert_data(1000000)
data.close_connection()
采用多线程实现
import random
import string
import mysql.connector
from threading import Thread, Lock
class InsertDataThread(Thread):
def __init__(self, conn, lock):
super(InsertDataThread, self).__init__()
self.conn = conn
self.lock = lock
# 生成随机姓名
def get_name(self):
str_char = ""
get_char = string.ascii_letters + string.digits
get_len = random.randint(6, 12)
for i in range(1, get_len + 1):
str_char += random.choice(get_char)
return str_char
# 获取性别
def get_sex(self):
return random.choice(["男", "女"])
# 获取年龄
def get_age(self):
return random.randint(18, 100)
# 生成并插入一条数据
def insert_one_data(self):
name = self.get_name()
sex = self.get_sex()
age = self.get_age()
cursor = self.conn.cursor()
sql = "INSERT INTO your_table_name (name, sex, age) VALUES (%s, %s, %s)"
val = (name, sex, age)
with self.lock:
cursor.execute(sql, val)
self.conn.commit()
cursor.close()
# 多线程执行插入数据
def run(self):
for _ in range(20000):
self.insert_one_data()
# 测试代码
if __name__ == '__main__':
conn = mysql.connector.connect(
host='localhost',
user='your_username',
password='your_password',
database='your_database_name'
)
lock = Lock()
threads = []
for _ in range(50):
thread = InsertDataThread(conn, lock)
thread.start()
threads.append(thread)
# 等待所有线程执行完毕
for thread in threads:
thread.join()
conn.close()