python基础 (v3.6.6)
day04
1. 文件读写:excel文件内容的读写
在python中,对excel表格读,写,追加数据,用以下四个模块:
1、xlrd 读取excel表中的数据,不可以编辑已有的xlsx格式的文件,只能读取、修改并保存xls格式的文件;
2、openpyxl 创建xlsx文件,也可以打开已经存在的xlsx文件进行编辑;不能操作xls格式的文件。
3、xlwt 创建一个全新的excel文件,然后对这个文件进行写入内容以及保存,只能修改并保存xls格式的文件;
4、xlutils 读入一个excel文件,然后进行修改或追加,不能操作xlsx,只能操作xls。
我们这里只学习openpyxl和xlrd模块对excel文档的常见读取方法。
1-1. openpyxl模块的使用
安装openpyxl: pip install openpyxl
1-1-1. 创建一个xlsx文件
import openpyxl
#创建文件
wb = openpyxl.Workbook()
#打开文件,并激活当前sheet页
wb.active
#保存文件
wb.save("test01.xlsx")
1-1-2. 向文件中写入数据 sheet.cell(行,列,值)
import openpyxl
#创建文件
wb = openpyxl.Workbook()
#打开文件,并激活当前sheet页
sh = wb.active
#写入数据
sh.cell(1,1,"用户名")
sh.cell(1,2,"密码")
#保存文件
wb.save("text02.xlsx")
# 练习:有以下列表
[ ['13058126836','abc123456'],
['13058126837','abc123457'],
['13058126838','abc123458'],
['13058126839','abc123459'] ]
请将该列表的数据,输入到excel中,第一列为用户名、第二列为密码
import openpyxl
#创建文件
wb = openpyxl.Workbook()
#打开文件,并激活当前sheet页
sh = wb.active
#写入数据
sh.cell(1,1,"用户名")
sh.cell(1,2,"密码")
accounts = [['13058126836','abc123456'],['13058126837','abc123457'],
['13058126838','abc123458'],['13058126839','abc123459']]
rownum = 2
colnum = 1
for i in accounts:
print(i)
sh.cell(rownum,colnum,i[0])
sh.cell(rownum,colnum+1,i[1])
#行数下移
rownum = rownum + 1
#保存文件
wb.save("text03.xlsx")
1-1-3. 读取Excel数据
import openpyxl
wb = openpyxl.load_workbook("../test03.xlsx") # 打开文件
sh = wb.active
print(sh.cell(2,1).value) # 读取指定单元格的值(第2行、第1列)
1-1-4. 修改Excel数据
import openpyxl
wb = openpyxl.load_workbook("../test05.xlsx")
sh = wb.get_sheet_by_name("Sheet") # 激活指定sheet页
sh.cell(2,1,"修改后的值") # 修改指定单元格的值
wb.save("../test05.xlsx")
1-1-5. 获取Excel所有行数和列数
import openpyxl
wb = openpyxl.load_workbook("../test05.xlsx")
sh = wb.get_sheet_by_name("Sheet")
print(sh.max_row) # 获取所有行数
print(sh.max_column) # 获取所有列数
## 练习33:将Excel表格内容全部输出
import openpyxl
wb = openpyxl.load_workbook("../test05.xlsx")
sh = wb.get_sheet_by_name("Sheet")
for row in range(1,sh.max_row+1):
for col in range(1,sh.max_column+1):
print(sh.cell(row,col).value, end="\t")
print()
1-2. xlrd模块的使用
使用openpyxl获取Excel文档所有行、列比较麻烦,可以使用xlrd
安装xlrd: pip install xlrd
xlrd的1.2.0版本同时支持xlsx和xls,而新版本只支持xls
安装xlrd旧版本:pip uninstall xlrd → pip install xlrd==1.2.0
1-2-1. 打开Excel文档
import xlrd
wb = xlrd.open_workbook("../test06.xls")
# 获取sheet页面
sh = wb.sheet_by_name("Sheet1") # 通过名称获取,常用
sh2= wb.sheet_by_index(0) # 通过索引顺序获取
sh3= wb.sheets()[0] # 通过索引顺序获取
1-2-2. 获取已经使用的行数和列数
nrows = sh.nrows
ncols = sh.ncols
print("行数:",nrows,"列数:",ncols)
1-2-3. 获取整行或整列的值,以列表形式返回
print(sh.row_values(0)) # 获取第1行的值
print(sh.col_values(1)) # 获取第2列的值
1-2-4. 获取指定单元格的值
# 获取第2行、第1列的值
print(sh.cell_value(1,0)) # 以字符串格式打印,常用
print(sh.cell(1,0)) # 以表格格式打印
## 练习35:按以下格式将Excel里面内容输出
# name psword
# tom a123456
# lily a123457
# lucy a123458
import xlrd
wb = xlrd.open_workbook("../test06.xls")
sh = wb.sheet_by_name("Sheet1")
nrows = sh.nrows # 获取行数
for i in range(nrows):
print(sh.row_values(i)[0],sh.row_values(i)[1])
# 方法2:使用zip()函数
import xlrd
wb = xlrd.open_workbook("../test06.xls")
sh = wb.sheet_by_name("Sheet1")
for j,k in zip(sh.col_values(0),sh.col_values(1)):
print(j,k)
2. 递归算法 (递去,归来)
递归的特点: 1.调用自身
2.结束调用自身的条件
说明:一层层调用自身,当不满足条件时,停止递归,开始归来
def func1(n):
if n > 0:
print(n)
func1(n-1)
func1(5) #打印结果→: 5,4,3,2,1
def func2(n):
if n > 0:
func2(n-1)
print(n)
func2(5) #打印结果→: 1,2,3,4,5
##练习1:从键盘输入一个整数,并求这个整数的阶乘。
def jie(arg):
if arg == 1:
return 1
else:
return arg * jie(arg-1)
num = int(input("请输入一个整数:"))
print(jie(num))
3. json数据的处理
JSON -- JavaScript Object Notation是一种轻量级的数据传输格式。
JSON 是要结合Ajax(异步请求)使用的,
在后端一般会将一个对象转换成JSON格式的数据,之后返回给客户端。
餐厅点餐,厨师做好菜需要用碗,把菜端给客户吃,碗就是json数据
JSON 的常规用途是同 web 服务器进行数据传输。
在从 web 服务器接收数据时,数据永远是字符串。
通过 JSON.parse() 解析数据,这些数据会成为 JavaScript 对象。
json可理解为双引号的字符串
3-1. 序列化
序列化:是把对象转换为字节序列,永久存到磁盘中。在网络中传输对象也要进行序列化。
将Python数据转换为json对应的数据格式,可简单理解为字典、列表、元组等转成字符串
# 字典转字符串
import json
dict1 = { "xiaowu": {
"sex": "男",
"cars": ["劳斯莱斯","五菱宏光"] },
"hong": {
"age": 18,
"sex": "女",
"bags": {"qianbao": ["lv","八匹狼"] } } }
# ensure_ascii=False是将unicode转换为中文,indent=4是缩进4个空格
res = json.dumps(dict1,ensure_ascii=False,indent=4)
print(type(res))
print(res)
3-2. 反序列化
反序列化:是从磁盘中读取字节序列将它们反序列化成对象读出来。
将json数据转换为Python对应的数据格式,可简单理解为字符串转为字典列表、元组等
# 字符串转成字典
import json
stu = '''
{ "xiaowu": {
"sex": "男",
"cars": ["劳斯莱斯","五菱宏光"] },
"hong": {
"age": 18,
"sex": "女",
"bags": {"qianbao": ["lv","七匹狼"] } } }
'''
# 转换字符串用loads(),如果是json文件则用load()
res = json.loads(stu)
print(type(res)) # →: dict
print(res["hong"]["bags"]["qianbao"][1]) # →: 七匹狼
# 补充接上:读取嵌套字典的value值,也可使用jsonpath.jsonpath()方法,返回列表形式
# 先安装jsonpath: pip install jsonpath
import jsonpath
print(jsonpath.jsonpath(res,"$..sex")[1]) # →: 女
print(jsonpath.jsonpath(stu,"$.hong.sex")[0]) # →: 女
3-3. 补充
# 序列化:将字典转成字符串,并保存到json文件中
dict1 = {"字典":"字典的值"}
import json
with open("../test06.json","w",encoding="utf-8") as f:
json.dump(dict1,f,ensure_ascii=False,indent=4)
# 反序列化:将json文件中的字符串转成字典
import json
with open("../test06.json","r",encoding="utf-8") as f2:
res2 = json.load(f2)
print(type(res2)) #字典格式
print(res2)
4. 面向对象
面向对象的语言:Java python C++ ruby php 等
面向对象的三个特点:
封装:将具有同一特点的属性、方法,写入一个类里面
继承:子类继承父类的所有特征(属性、方法)
多态:在子类中重写父类的属性或方法,让子类拥有和父类不同的形态(值)
类:类是一些具有相同属性或者方法的集合,类名首字母一般要大写
类的属性:类里面的变量,在类里面且在函数体之外定义,属于全局变量。
类的方法:类里面的函数
类的实例化:创建一个类的实例,即对象
对象 = 属性 + 方法
比如兔子是对象,有静态特征、动态行为
属性:三瓣嘴、长耳朵、红眼睛
方法:跑、跳、吃东西
class 类名():
类的属性
类的方法
注:定义类时若无继承父类,类名后面的括号可省略,根据个人习惯来
4-1. 类的属性和方法
# 类的方法,不需要传参,方法里面访问类属性时,属性前面加上self.
class Car(): # 类名首字母大写
color = '白色' # 定义属性
brand = '宾利'
def def1(self): #定义方法
return '车的颜色是'+ self.color + ',品牌是'+ self.brand
c = Car() # 类的实例化,也叫对象
print(c.brand) # 访问类的属性
print(c.def1()) # 访问类的方法
# 类的方法,需要从外面传参,不写self.
class Car():
color = '白色'
brand = '宾利'
def def2(self,brand):
return self.color + brand
c = Car() # 类的实例化,也叫对象
print(c.brand) # 访问类的属性
print(c.def2('大众')) # 访问类的方法,传参
print(c.def2(brand='法拉利'))
注:如果def2里面,return的brand写成self.brand,打印def2都是:白色宾利
4-2. 代码较长时,可换行 \
user = "我叫tom,\
今年20岁"
print(user) # →: 我叫tom,今年20岁
4-3. self
类的方法,第一个参数必须是self,但是使用时,无需传参!
self相当于房子的门牌号
# 查看self的区别
class Room():
def func(self):
return self
r = Room()
r2= Room()
print(r.func())
print(r2.func())
注:r和r2相当于两个不同的房子,所以self的值也不同
4-4. 构造函数
类有一个名为 __init__() 的特殊方法,属于类的专有方法,该方法在类实例化时会自动调用。
构造函数不是必须要有的,主要作用是用来在创建对象时完成对对象属性的一些初始化等操作。 通常,当系统一启动就需要获取的数据,我们可以定义到构造函数里面来。
class Room():
def __init__(self):
print("我是构造函数")
def func(self):
return "我是func函数"
r = Room() # →: 我是构造函数
# 构造函数有参数时,实例化对象时需要传参
class Room():
def __init__(self,name):
print("我是构造函数")
self.name = name
def func(self):
#return "我是func函数,我叫%s"%self.name
return "我是func函数,我叫" + self.name
r = Room("tom")
print(r.func())
4-5. 单继承
class Xiaomi():
brand = '小米'
color = '白色'
camera = '无敌'
def def1(self):
return '颜色是'+ self.color
class Redmi(Xiaomi):
brand = '红米'
color = '红色' #重写
def def2(self):
return '品牌是'+ self.brand + self.camera
mi = Redmi()
print(mi.def2()) #→:品牌是红米无敌
print(mi.color) #→:红色
print(mi.camera) #继承父类,→:无敌
print(mi.def1()) #继承父类,→:颜色是白色
4-6. 类的私有属性和私有方法
单个或两个_开头的属性或方法,为私有属性或私有方法,不能导入到别的模块中使用
总结:
单个_开头的私有属性和私有方法,可以被当前类使用,也可以被自己的对象使用,
还可以被子类和子类的对象使用;
两个_开头的私有属性和私有方法,可以被当前类使用,但不能被自己的对象使用,
也不能被子类和子类的对象使用。
class Car():
_aa1 = "我是_aa1 "
__aa2 = "我是__aa2 "
def _fun1(self):
return "我是_fun1 "
def __fun2(self):
return "我是__fun2 "
def all(self):
return self._aa1 + self.__aa2 + self._fun1() + self.__fun2()
c = Car() # 创建对象
print(c._aa1) # 可以被对象使用(正常访问)
print(c._fun1()) # 可以被对象使用(正常访问)
print(c.__aa2) # 不能被对象使用(报错)
print(c.__fun2()) # 不能被对象使用(报错)
print(c.all()) # 可以被类使用(正常访问)
----------------------------------------------
class Car2(Car):
def all2(self):
return self._aa1 + self._fun1()
c2 = Car2()
print(c2._aa1) # 可以被子类对象使用(正常访问)
print(c2._fun1()) # 可以被子类对象使用(正常访问)
print(c2.all2()) # 可以被子类使用(正常访问)
4-7. pass
占位符,当方法里面没有内容时,防止出现语法错误。
4-8. super()函数
在子类中使用super()方法调用被重写的父类的方法或属性
class Xiaomi():
color = "白色"
class Redmi(Xiaomi):
color = "红色"
def fun(self):
return "我的手机是" + self.color
def fun2(self):
return "我的手机是" + super().color
m = Redmi()
print(m.fun()) # →: 我的手机是红色
print(m.fun2()) # →: 我的手机是白色(调用父类属性)
print(super(Redmi,m).color) # 白色(调用父类属性)