6. 模块pickle\json\random\os\zipfile\面对对象(类的封装 操作 __init__)

1.模块

1.1 pickle模块
# ### pickle 序列化模块 import pickle """ 序列化: 把不能够直接存储的数据变得可存储 反序列化: 把数据恢复成原本的数据格式 serialize 序列化 unserialize 反序列化 """ # 正常情况下,不能够直接把容器类型数据等直接存储在文件当中 """ with open("ceshi.txt",mode="w",encoding="utf-8") as fp: lst = [1,2,3] fp.write(lst) """ #dumps 把任意对象序列化成一个bytes lst = [1,2,3,4,5] res = pickle.dumps(lst) print(res) #loads 把任意bytes反序列化成原来数据 res = pickle.loads(res) print(res,type(res)) # 序列化函数 def func(): print("我是一个函数") res = pickle.dumps(func) print(res) # 反序列化函数 func = pickle.loads(res) func() # 序列化迭代器 from collections import Iterator,Iterable it = iter(range(10)) print(isinstance(it,Iterator)) res = pickle.dumps(it) print(res) res = pickle.loads(res) print(res) for i in res: print(i) # dumps 和 loads 把数据存储在文件 setvar = {"a","b"} with open("ceshi.txt",mode="rb+") as fp: res = pickle.dumps(setvar) fp.write(res) # 读取内容的时候,先把光标移动的文件行首. fp.seek(0) res2 = fp.read() print(res2) setvar = pickle.loads(res2) print(setvar,type(setvar)) #dump 把对象序列化后写入到file-like Object(即文件对象) def func2(): print("我是func2") with open("ceshi02.txt",mode="wb") as fp: # 参数1:要序列化的数据 参数2:对应的文件对象 pickle.dump(func2,fp) #load 把file-like Object(即文件对象)中的内容拿出来,反序列化成原来数据 with open("ceshi02.txt",mode="rb") as fp: func = pickle.load(fp) # 调用函数 func() # pickle模块可以序列化所有的数据类型.

1.2 json模块

# ### json
import json
"""
json可以序列化数据,转化成一个字符串.
json格式的数据,可以让所有的编程语言都能够识别,
有数据类型的限制:bool float int list tuple dict str None
"""

# 第一组:dumps 和 loads 用来序列化或反序列化字符串
"""
ensure_ascii=True 是否显示中文 设置ensure_ascii=False 显示中文
sort_keys=True 对字典的键按照ascii进行排序
"""
dic = {"name":"李祖清","age":58,"sex":"man","family":["爸爸","妈妈","姐姐","妹妹"]}
res = json.dumps(dic,ensure_ascii=False,sort_keys=True)
print(res,type(res))

dic = json.loads(res)
print(dic,type(dic))

# 第二组: dump 和 load 用来对数据进行存储
dic = {"name":"李祖清","age":58,"sex":"man","family":["爸爸","妈妈","姐姐","妹妹"]}
with open("ceshi03.json",mode="w",encoding="utf-8") as fp:
json.dump(dic,fp,ensure_ascii=False)

with open("ceshi03.json",mode="r",encoding="utf-8") as fp:
dic = json.load(fp)

print(dic,type(dic))

# json 和 pickle 两个模块的区别?

# json 用法特征:
"""
json 可以连续dump,但是不能连续load
load 只可以load一次,它是一次性把所有的数据作为一个整体来进行转化
可以使用loads 来进行解决
"""
dic1 = {'a':1,"b":2}
dic2 = {"c":3,"d":4}

with open("ceshi04.json",mode="w",encoding="utf-8") as fp:
json.dump(dic1,fp)
fp.write("\n")
json.dump(dic2,fp)
fp.write("\n")

# error 只能load一次,是一次性把所有数据转化.
"""
with open("ceshi04.json",mode="r",encoding="utf-8") as fp:
res = json.load(fp)
print(res)
"""
# 解决方式
with open("ceshi04.json",mode="r",encoding="utf-8") as fp:
for line in fp:
res = json.loads(line)
print(res)


# pickle 用法特征:
import pickle
"""
pickle 可以连续dump,也可以连续load
"""
dic1 = {'a':1,"b":2}
dic2 = {"c":3,"d":4}

with open("ceshi05.pkl",mode="wb") as fp:
pickle.dump(dic1,fp)
pickle.dump(dic2,fp)

with open("ceshi05.pkl",mode="rb") as fp:
try:
while True:
dic = pickle.load(fp)
print(dic)
except:
pass
print(333)

# 文件对象是迭代器么? 是的!
from collections import Iterator
print(isinstance(fp,Iterator))

"""
try ... except ...
把有问题的代码直接卸载try这个代码块当中,
如果出现异常,直接走except这个代码块,防止报错终止程序.
try:
print(wangwendashuaiguo)
except:
pass
"""


# 总结:
"""

# json 和 pickle 两个模块的区别:
(1)json序列化之后的数据类型是str,所有编程语言都识别,
但是仅限于(int float bool)(str list tuple dict None)
json不能连续load,只能一次性拿出所有数据
(2)pickle序列化之后的数据类型是bytes,
所有数据类型都可转化,但仅限于python之间的存储传输.
pickle可以连续load,多套数据放到同一个文件中

"""

1.3 random模块

# ### random 随机模块
import random#random() 获取随机0-1之间的小数(左闭右开) 0<= x < 1
res = random.random()
print(res)

#randrange() 随机获取指定范围内的整数(包含开始值,不包含结束值,间隔值)

# 0 1 2 不包含3
res = random.randrange(3)
print(res)

# 1 ~ 4
res = random.randrange(1,5)
print(res)

# 1 4 7
res = random.randrange(1,10,3)
print(res)

#randint() 随机产生指定范围内的随机整数 (必须两个参数) (了解)
# 1 2 3 4
res = random.randint(1,4)
print(res)
# randint是给1个还是给3个都是错误的,只能给2个参数
# res = random.randint(1,10,3)


#uniform() 获取指定范围内的随机小数(左闭右开) 1 <= x < 3
res = random.uniform(1,3) # 推荐写法
print(res)
res = random.uniform(2,-1) # 不推荐
print(res)

# a = 2 b =-1
# return a + (b-a) * self.random() (0<= x < 1)
# self.random() # -1 < x <= 2
# 2 + (-1-2) * 0 = 2
# 2+ (-1-2) * 1 = 2 - 3 = -1
# 2


#choice() 随机获取序列中的值(多选一)
lst = ["舒则会","郭一萌","银燕","廖萍萍"]
res = random.choice(lst)
print(res)

# 自定义choice
def mychoice():
length = len(lst)
res = random.randrange(0,length)
return lst[res]
print(mychoice())

#sample() 随机获取序列中的值(多选多) [返回列表]
lst = ["舒则会","郭一萌","银燕","银燕2","廖萍萍","刘璐"]
lst = random.sample(lst,3)
print(lst)

#shuffle() 随机打乱序列中的值(直接打乱原序列)
lst = [1,2,3,4,5]
random.shuffle(lst)
print(lst)

# 随机验证码
def yanzhengma():
strvar = ""
for i in range(4):
# a~z 97 ~ 122 获取小写字母
res1 = chr(random.randrange(97,123))
# A~Z 65 ~ 90 获取大写字母
res2 = chr(random.randrange(65,91))
# 0~9 获取0~9 十个数字
res3 = random.randrange(0,10)
# 把可能的字符放到列表当中
lst = [res1,res2,res3]
# 拼接字符串
strvar += str(random.choice(lst))
# 返回字符串
return strvar

res= yanzhengma()
print(res)

1.4 os模块

# ### os 模块 对系统进行操作
import os

#system() 在python中执行系统命令
# os.system("mspaint")
# os.system("ipconfig")

#popen() 执行系统命令返回对象,通过read方法读出字符串,不会乱码
obj = os.popen("ipconfig")
print(obj.read())

#listdir() 获取指定文件夹中所有内容的名称列表
"""
. 代表的是当前路径
.. 代表的是上一级路径
"""
res = os.listdir(".")
print(res) # ['1.py', '2.py', '20190728_1.json_pickle.mp4', '3.py', '4.py', 'ceshi.txt', 'ceshi02.txt', 'ceshi03.json', 'ceshi04.json', 'ceshi05.pkl', 'ceshi_shengyin.mp4', 'part10.md', 'part11.md']

#getcwd() 获取当前文件所在的默认路径
res = os.getcwd()
print(res) # D:\周末四期\L006
print(__file__) # 完整路径(外加文件名)




#os.mkdir 创建目录(文件夹)
# os.mkdir("ceshi100")
# os.rmdir 删除目录(文件夹)
# os.rmdir("ceshi100")
#os.rename 对文件,目录重命名
# os.rename("ceshi100","ceshi200")

#copy(src,dst) #复制文件权限和内容
# import shutil
# shutil.copy("ceshi02.txt","ceshi333.py")


#chdir() 修改当前文件工作的默认路径
# os.chdir(r"D:\周末四期\L005")
# os.mkdir("ceshi200")

#environ 获取或修改环境变量
# print(os.environ)
# os.system("QQScLauncher")

# environ 返回的是字典,通过path环境变量,追加路径,在执行命令的时候,一个一个路径取找,如果找到了直接执行,反之报错
'''
print(os.environ["PATH"])
os.environ["PATH"] += r""";C:\Program Files (x86)\Tencent\QQ\Bin"""
os.system("QQScLauncher.exe")
'''

#--os 模块属性
#name 获取系统标识 linux,mac ->posix windows -> nt
print(os.name)
#sep 获取路径分割符号 linux,mac -> / window-> \
print(os.sep)
#linesep 获取系统的换行符号 linux,mac -> \n window->\r\n 或 \n
print(repr(os.linesep))


1.5 os.path 路径
# ### os.path
import os
#abspath() 将相对路径转化为绝对路径
res = os.path.abspath(".")
print(res)

#basename() 返回文件名部分 5颗星
pathvar = r"D:\周末四期\L006\filename.py"
res = os.path.basename(pathvar)
print(res)

#dirname() 返回路径部分 5颗星
pathvar = r"D:\周末四期\L006\filename.py"
res = os.path.dirname(pathvar)
print(res)

# 获取当前文件所在的路径 5颗星
print(os.getcwd())
# 获取完整文件路径 5颗星
print(__file__)

#split() 将路径拆分成单独的文件部分和路径部分 组合成一个元组
# ('D:\\周末四期\\L006', 'filename.py')
pathvar = r"D:\周末四期\L006\filename.py"
res = os.path.split(pathvar)
print(res)


#join() 将多个路径和文件组成新的路径 可以自动通过不同的系统加不同的斜杠 linux / windows\ 5颗星
"""
linux : /home/wangwen/a.py
windows: d:\周末四期\L006\filename.py

# 绝对路径
以 / 开头的是绝对路径 linux
以 盘符开头的完整路径是绝对路径 windows

# 相对路径
. 当前路径
.. 上一级路径

"""
path1 = "周末四期"
path2 = "L006"
path3 = "filename.py"
res = os.path.join(path1,path2,path3) # 推荐
print(res)
res = path1 + os.sep + path2 + os.sep + path3
print(res)

#splitext() 将路径分割为后缀和其他部分
pathvar = r"d:\周末四期\L006\filename.py"
res = os.path.splitext(pathvar)
print(res)

#getsize() 获取文件的大小 5颗星
pathvar = r"D:\周末四期\L006\4.py"
res = os.path.getsize(pathvar)
print(res)

pathvar = r"D:\周末四期\L006"
#isdir() 检测路径是否是一个文件夹 (重点记) 5颗星
res = os.path.isdir(pathvar)
print(res)

#isfile() 检测路径是否是一个文件 (重点记) 5颗星
pathvar = r"D:\周末四期\L006\4.py"
res = os.path.isfile(pathvar)
print(res)

#islink() 检测路径是否是一个链接 (了解)
pathvar = r"D:\周末四期\L006\4.py"
res = os.path.islink(pathvar)
print(res)

#getctime() [windows]文件的创建时间,[linux]权限的改动时间(返回时间戳)
pathvar = r"D:\周末四期\L006\4.py"
res = os.path.getctime(pathvar)
print(res)
import time
str_time = time.ctime(res)
print(str_time)

#getmtime() 获取文件最后一次修改时间(返回时间戳)
res = os.path.getmtime(pathvar)
print(res)
import time
str_time = time.ctime(res)
print(str_time)
#getatime() 获取文件最后一次访问时间(返回时间戳)
res = os.path.getatime(pathvar)
print(res)
import time
str_time = time.ctime(res)
print(str_time)

#exists() 检测指定的路径是否存在 5颗星
res = os.path.exists(r"D:\周末四期\L006\4.py")
print(res)

#isabs() 检测一个路径是否是绝对路径 abspath 4颗星
"""
别人传变量给你,先判断是不是绝对路径,如果不是用abspath配合转换.
"""
strvar = "."
res = os.path.isabs(strvar)
print(res)

1.6 例子计算一个文件夹内所有的文件大小(递归函数)
# ### 计算一个文件夹所有文件的大小
import os
path1 = os.getcwd()
# print(path1)
pathvar = os.path.join(path1,"ceshi300")
# D:\周末四期\L006\ceshi300
print(pathvar)



# part1 基本操作
lst = os.listdir(pathvar)
print(lst)

# 初始化变量size = 0
size = 0
for i in lst:

# 拼接成完整的绝对路径
pathnew = os.path.join(pathvar,i)
# 判定它是不是文件
if os.path.isfile(pathnew):
print(i,"是一个[文件]")
# 如果是文件,计算大小 getsize 只能算文件的大小
size += os.path.getsize(pathnew)
# 判定它是不是文件夹
elif os.path.isdir(pathnew):
print(i,"是一个[文件夹]")
print(size) # 4834


# part2 递归方法计算文件夹里所有内容大小
def getallsize(pathvar):

size = 0
lst = os.listdir(pathvar)

for i in lst:
pathnew = os.path.join(pathvar,i)
if os.path.isfile(pathnew):
print(pathnew)
# 统计文件大小
size += os.path.getsize(pathnew)
elif os.path.isdir(pathnew):
print(pathnew) # D:\周末四期\L006\ceshi300\ceshi400
# 递归统计文件夹里面的文件名称
size += getallsize(pathnew)

return size
res = getallsize(pathvar)
print(res) # 6882 + 953 2048 4834


1.7 zipfile压缩文件
# ### zipfile 压缩模块 后缀是 zip
import zipfile

# [part1] 压缩文件

# 1.创建压缩包
zf = zipfile.ZipFile("ceshi01.zip","w",zipfile.ZIP_DEFLATED)

# 2.写入文件
# write(路径,别名)
zf.write(r"D:\周末四期\L006\1.py","1111.py")
zf.write(r"D:\周末四期\L006\2.py","22222.py")
# 可以在写入文件的同时,创建一个文件夹
zf.write(r"D:\周末四期\L006\3.py","tmp/333.py")

# 3.关闭文件
zf.close()

# [part2] 解压文件
zf = zipfile.ZipFile("ceshi01.zip","r")
"""
extractall 解压所有
extract 解压单个文件
"""
# 解压所有文件到某个路径下 ./代表当前路径下的某个文件夹sdf
zf.extractall("./ceshi001")
# extract 解压单个文件
zf.extract("1111.py","./ceshi002")
zf.close()

# [part3] 追加文件 自动完成关闭zip压缩包操作
with zipfile.ZipFile("ceshi01.zip","a",zipfile.ZIP_DEFLATED) as zf:
zf.write("5.py")

# [part4] 查看压缩包中的内容
with zipfile.ZipFile("ceshi01.zip","r",zipfile.ZIP_DEFLATED) as zf:
lst = zf.namelist()

print(lst)

 2. 面向对象

2.1 面向对象 oop

# ### 面向对象 oop
"""
用几大特征表达一类事物称为一个类,类更像是一张图纸,表达的是一个抽象概念

#对象是类的具体实现,更像是由这图纸产出的具体物品,类只有一个,但对象可以通过这个类实例化出多个
"""

# (1)类的定义
class MyClass:
    pass
    
# 推荐写法
class MyClass():
    pass

class MyClass(object):
    pass

# (2)类的实例化
class Car():
    color = "蓝色"
# 类的实例化 产生的是对象
obj = Car()
print(obj)


# (3)类的基本结构
"""
类中只有两样东西:
    (1)成员属性
    (2)成员方法
"""
# 标准写法
class MyCar():
    # 成员属性
    color="红色"
    # 成员方法
    def run():
        pass

# 例外不标准写法,不推荐使用
"""
类中的逻辑,在定义类的时候,直接执行,这个写法语法上不报错,
但是严令禁止使用
"""
class MyCar():
    if 5==5 :
        print(1233)

# 改造
class MyCar():
    def func():
        if 5==5 :
            print(1233)


# (4)类的命名
"""
推荐使用驼峰命名法:
    每个单词首字符大写;
    myclass => MyClass
    mycar => MyCar
    iloveboy => ILoveBoy
"""

2.2 类的封装
# ### 封装
"""
# 对象的使用方式:
对象.属性
对象.方法()

"""
class MyCar():
# 公有成员属性
pinpai = "布加迪威行"

# 私有成员属性
__oil = "2.5L"

# 公有成员方法
def run(self):
# self.pinpai <==> obj.pinpai
print("我的小车会跑",self.pinpai)

# 私有成员方法
def __oil_info(self):
print("油耗信息是保密的")
"""
绑定方法:
(1) 绑定到对象 : 系统会默认把对象当成参数进行传递,让self形参进行接收. ( 对象.方法 )
(2) 绑定到类 : 系统会默认把类当成参数进行传递,让形参进行接收.( 对象.方法 或 类.方法 通过装饰器修饰)
"""
# 实例化对象 或者 类的实例化 两个名字都可以,都是产生对象
obj = MyCar()


#(1)实例化的对象访问公有成员属性和方法
print(obj.pinpai)
# obj.run(),系统自动把obj这个对象当成参数传递给run方法中self这个参数进行接收.
obj.run()

# (2)实例化的对象动态添加公有成员属性和方法
# __dict__ 可以获取对象或者类的内部成员 , 它是魔术属性.
print(obj.__dict__) # 第一次为什么打印? 想要告诉你当前对象obj,没有成员 {}
obj.color = "屎黄色" # 添加成员
print(obj.color ) # 屎黄色
print(obj.__dict__) # {'color':'屎黄色'}

# 动态添加成员方法
# (1) 添加无参方法
def fangxiangpan():
print("我是制造方向盘的方法")

# 让类外的函数赋值给obj对象的成员方法fangxiangpan
obj.fangxiangpan = fangxiangpan
obj.fangxiangpan()
print(obj.__dict__)

# (2) 添加有参方法
def func(self,something):
print(self.pinpai,something)
# 将右侧的值赋值给左侧的成员属性func
obj.func = func
# 需要手动把对象传进去,不如使用绑定方法
obj.func(obj,"有参方法")


# 使用绑定方法自动把obj当成参数传递 依靠 MethodType
import types
# MethodType(函数,要绑定在哪个对象上)
# 将创建的绑定方法赋值给成员属性func2,意味着下次调用不需要手动传递该对象,系统会自动帮你传递;
obj.func2 = types.MethodType(func,obj)
obj.func2("有参方法")


# (3) 添加lambda表达式

obj.dahuangfeng = lambda : print("请叫我大黄蜂")
obj.dahuangfeng()
obj.qingtianzhu = lambda n : print(n)
obj.qingtianzhu("擎天柱")


# obj.pinpai = "abc"
print(obj.pinpai)

2.3 类的相关操作

# ### 类的相关操作
"""
语法:
类.属性
类.方法()
"""
class Plane():
# 公有成员属性
captain = "李祖清"
# 私有成员属性
__air_sistem = 20

# 普通公有方法
def fly():
# 灰机会飞 20
print("灰机会飞",Plane.__air_sistem)
# 普通私有方法
def __fly2():
print("空姐数量是保密的")

obj = Plane()
# 对象无法调用无参的普通方法,必须要加上self
# obj.fly() error
# (1)定义的类访问公有成员属性和方法

print(Plane.captain)
# 无论是对象还是类,都无法在类外调用类中的私有成员
# print(Plane.__air_sistem) error
Plane.fly()

# 查看类Plane的所有成员
print(Plane.__dict__)



# (2)定义的类动态添加公有成员属性和方法
Plane.engine = "烧汽油的"
print(Plane.__dict__)
print(obj.__dict__)

# 添加方法
# (1)无参方法
def bianxing():
print("我的飞机能变成小鸟")
Plane.bianxing = bianxing
Plane.bianxing()


# (2)有参方法
def setname(name):
print("我的飞机名",name)
Plane.setname = setname
Plane.setname("空军一号")


# (3)lambda表达式
Plane.lunzi = lambda : print("我是制造飞机轮胎的方法")
Plane.lunzi()


"""
调用类中成员的时候,要么使用对象,要么使用类来调用,不能直接写.
对象可以使用类中的相关公有成员,但是没有归属权,
类中的成员都归当前这个类所有,但是不能使用对象中的相关成员

对象中如果有这个成员,用对象自己的
如果没有,用类中的成员.
"""
2.4 删除类对象中的成员

# ### 删除类对象中的成员
class MyCar():
price="100元"
__oil= "百公里1升"

# 普通方法
def bianxing_cat1():
print("车会变形成猫",MyCar.price)

# 绑定到对象方法
def bianxing_cat2(self):
print("车会变形成猫",self.price)

# 普通私有方法
def __oil_info1():
print("油耗信息保密")

# 私有绑定方法
def __oil_info2(self):
print("油耗信息保密")

# 定义公有绑定方法
def pub_func(self):
print(self.__oil)
self.__oil_info2()

# 定义公有普通方法
def pub_func2():
print(MyCar.__oil)
MyCar.__oil_info1()

# 实例化对象
obj = MyCar()
print(obj.__dict__)
print(MyCar.__dict__)

# (1)实例化的对象删除公有成员属性和方法
obj.price = "2元" # 动态为该对象付成员属性price
print(obj.price)
del obj.price # 删除成员属性
print(obj.price)

# func这个成员是一个静态方法,无论是类还是对象都能当成普通方法调用,
"""在类外动态添加成员方法,返回的是静态方法."""
obj.func = lambda n : print("我是func函数",n)
obj.func(123)
# del obj.func # 删除方法
# obj.func(123) # 删除之后无法调用

# (2)定义的类删除公有成员属性和方法
# del MyCar.price
# print(MyCar.price)
# print(obj.price) # 对象无法调用
# MyCar.func(123) # 类无法调用对象中的成员


# del MyCar.bianxing_cat1
# MyCar.bianxing_cat1()

# (3) 可否在类外调用私有成员?
"""
改名策略:
_类名+私有成员名:比如
__oil => _MyCar__oil
__oil_info1 => _MyCar__oil__oil_info1
"""
# 对象的调用
print(obj._MyCar__oil)
obj._MyCar__oil_info2()
# 类的调用
print(MyCar._MyCar__oil)
MyCar._MyCar__oil_info1()
# obj.bianxing_cat2()

print("<==>")
# (4)通过公有方法,调用私有成员
obj.pub_func()
MyCar.pub_func2()

2.5 __int__构造方法
# ### 构造方法 __init__
#__init__魔术方法(构造方法)
'''
触发时机:实例化对象,初始化的时候触发
功能:为对象添加成员
参数:参数不固定,至少一个self参数
返回值:无
'''

# (1) 基本语法
class MyClass():
def __init__(self):
self.name = "廖萍萍"

# 实例化对象
obj = MyClass()
print(obj.name)

# (2) 多个参数的__init__
class MyClass():
def __init__(self,name):
# self.name (成员属性name) = name (参数name)
self.name = name

# 实例化对象的同时,在括号中加上对应的参数,self是系统自己传递的,name需要手动传递 郭一萌会被name形参接收走,在实例化的时进行赋值.
obj = MyClass("郭一萌")
print(obj.name)

# (3) 综合实力: 类可以有一个,对象可以有多个,不同的对象之间彼此数据隔离
class Children():
def __init__(self,name,skin):
self.name = name
self.skin = skin

def cry(self):
print("小孩一下生就哭")

def eat(self):
print("小孩饿了喝奶奶")

def sleep(self):
print("小孩一天23个小时睡觉,还有一个小时上厕所")

def child_info(self):
print("该对象姓名:{},肤色是{}".format(self.name,self.skin))

# 实例化对象1
child1 = Children("王铁杵","黑色")
child1.cry()
child1.child_info()

# 实例化对象2
child2 = Children("廖凡","屎黄色")
child2.eat()
child2.child_info()

# 实例化对象3
child3 = Children("王宝强","绿色的")
child3.sleep()
child3.child_info()
posted @ 2019-08-03 12:26  善战者求之于势  阅读(235)  评论(0编辑  收藏  举报