【有书共读】python带我起飞读书笔记08
第8章 文件操作-—数据持久化的一种方法
1. 带有异常处理的文件操作
实例描述
对文件分别进行写入和读取操作行关闭。并且都使用except进行异常处理,最终在finally中进
(1)在第一个try里面,以二进制形式打开一个文件,串。使用excePt对try里面的异常进行捕获。最终在finally以文本的方式向里面写入一个字符中对文件进行关闭。
(2)在第二个try里面,以文本的方式打开一个文件,并读取里面的内容。使用 except 对 try 里面的异常进行捕获。最终在 finally 中对文件进行关闭。
对文件分别进行写入和读取操作行关闭。并且都使用except进行异常处理,最终在finally中进
(1)在第一个try里面,以二进制形式打开一个文件,串。使用excePt对try里面的异常进行捕获。最终在finally以文本的方式向里面写入一个字符中对文件进行关闭。
(2)在第二个try里面,以文本的方式打开一个文件,并读取里面的内容。使用 except 对 try 里面的异常进行捕获。最终在 finally 中对文件进行关闭。
第一个 try 故意放置了一段错误代码,以文本的方式写入一个用二进制打开的文件是会报错的,程序会跳到 except 的异常捕获分支里,最终在 finally 中关闭文件。
第二个 rty 则是正确的代码,程序不会报异常,但也会进入finally模块关闭文件。
代码:
try: f = open('a.txt','wb+') #以二进制的方式打开一个文件 f.write('I like Python!') #以文本的方式写入一个用二进制打开的文件,会报错 except Exception as e: #将错误异常捕获 print(e ) f.write(b'I like Python!') #以bytes对象的形式进行读写 finally: #无论程序是否错误,在执行完前面代码后,都要在这里关闭文件 print("关闭文件") f.close() #关闭文件 try: f = open('a.txt','r+') #打开文件 for line in f: #直接使用for循环读取文件 print(line) #将内容打印出来 finally: f.close() #关闭文件
运行结果:
使用 with 语句对文件分别进行写入和读取操作,并且使用 try/except 进行异常处理。
(l)在第一个 with 里,以二进制形式打开一个文件,以文本的方式向其中写入一个字符串,并使用 except 语句捕获异常。
(2)在第二个with里,以文本的方式打开一个文件,并读取里面的内容,并使用 except 语句捕获异常。
代码:
(l)在第一个 with 里,以二进制形式打开一个文件,以文本的方式向其中写入一个字符串,并使用 except 语句捕获异常。
(2)在第二个with里,以文本的方式打开一个文件,并读取里面的内容,并使用 except 语句捕获异常。
代码:
with open('a.txt','wb+') as f: #以二进制的方式打开一个文件 try: f.write('I like Python!') #以文本的方式写入一个用二进制打开的文件,会报错 except Exception as e: #将错误异常捕获 print(e ) f.write(b'I like Python!') #以bytes对象的形式进行读写 with open('a.txt','r+') as f: #打开文件 for line in f: #直接使用for循环读取文件 print(line) #将内容打印出来运行结果:
3. pickle函数的使用
定义一个含有多种类型元素的元组,分别对其进行如下操作:
(1)使用pickle函数将元组转成二进制对象,然后再从二进制对象还原回来,观察其值是否有变化。
(2)使用pickle函数将元组转成二进制对象文件,然后再从二进制对象文件中还原回来,观察其值是否有变化。
(1)使用pickle函数将元组转成二进制对象,然后再从二进制对象还原回来,观察其值是否有变化。
(2)使用pickle函数将元组转成二进制对象文件,然后再从二进制对象文件中还原回来,观察其值是否有变化。
代码:
import pickle #导入pickle模块 tup1 = ('I love Python', [1, 2, 3], None) #定义一个复杂元素类型的元组 #测试Python对象与二进制对象互转 p1 = pickle.dumps(tup1) #使用pickle模块的dumps将Python对象转成二进制对象 t2 = pickle.loads(p1) #使用pickle模块的loads将二进制对象转成Python对象 print(t2) #将其输出 #测试Python对象与二进制文件互转 path = "a.pkl" with open(path, 'wb') as f: pickle.dump(tup1, f, pickle.HIGHEST_PROTOCOL)#使用pickle模块的dump将Python对象转成二进制对象文件 with open(path, 'rb') as f: t3 = pickle.load(f) #使用pickle模块的load将二进制对象文件转成Python对象 print(t3) #将其输出运行结果:
4. 批量读取及显示 CT 医疗影像数据
代码:
import dicom #安装 import os def load_scan(path): slices = [dicom.read_file(path + '/' + s) for s in os.listdir(path)] return slices INPUT_FOLDER = "patient32/P32dicom" first_patient = load_scan(INPUT_FOLDER ) print(first_patient[0]) print(first_patient[0].dir() ) print(first_patient[0].dir("pat") ) print(first_patient[0].PatientName ) ##原始二进制文件 #pixel_bytes = first_patient[0].PixelData ##CT值组成了一个矩阵 #pix = first_patient[0].pixel_array ##读取显示图片 import pylab pylab.imshow(first_patient[0].pixel_array, cmap=pylab.cm.bone) pylab.show() ##################################批量显示 import PIL.Image as Image import math def plot_ct_scan(scan): #获取文件夹内的文件个数 length = len(scan) #根据总面积求每一个的大小 each_size = int(math.sqrt(float(810*810)/length)) #每一行可以放多少个 lines = int(810/each_size) #生成白色背景新图片 image = Image.new('RGBA', (810, 810),'white') x = 0 y = 0 for i in range(0,length): img=Image.fromarray(scan[i].pixel_array.astype(int))#numpy.ndarray类型,还得是整数 img = img.resize((each_size, each_size), Image.ANTIALIAS) #resize image with high-quality image.paste(img, (x * each_size, y * each_size)) x += 1 if x == lines: x = 0 y += 1 image.save('./' + "all.jpg") plot_ct_scan(first_patient)
第9章 类—面向对象的编程方案
1.类的相关术语
在Python中,类相关的面向对象术语如下:
2. 类的继承
创建一个父类,实现其初始化函数,再创建一个子类继承该父类。同时做如下实验。
(1)验证子类继承父类的初始化函数(子类中没有实现初始化函数):当通过子类实例化对象并传入初始值时,分析是否能实例化成功。
(2)验证子类覆写父类方法:在子类与父类中实现同样函数名的方法,通过子类实例化对象,并调用该方法时,观察父类的方法是否被调用。
父类Record实现了_init_ 函数和 showrecode 方法。子类 GirlRecord 中实现了 showrecode 方法,没有实现_init_函数。在子类的 showrecode 方法中,调用了父类 showrecode 方法。
在Python中,类相关的面向对象术语如下:
- 类(class):用来描述具有相同的属性和方法的对象的集合。它定义了该集合中所有对象共有的属性和方法。
- 类变量:类变量在所有实例化对象中是公用的。类变量定义在类中,且在函数体之外。类变量通常不作为实例变量使用。
- 数据成员:类变量或者实例变量,用于处理类及其实例对象的相关数据。
- 方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称作方法的重写。
- 实例变量:定义在方法中的变量,只作用于当前实例的类。
- 继承:即派生类(derived class)具有基类(base class)一样的字段和方法。继承会把一个派生类的对象作为一个基类对象对待。
- 实例化:创建一个类的实例,即得到类的具体对象。
- 方法:类中所定义的函数,也叫作该类的成员函数。
- 对象:对象是类的实例。对象包括两个数据成员(类变量和实例变量)和方法。
创建一个父类,实现其初始化函数,再创建一个子类继承该父类。同时做如下实验。
(1)验证子类继承父类的初始化函数(子类中没有实现初始化函数):当通过子类实例化对象并传入初始值时,分析是否能实例化成功。
(2)验证子类覆写父类方法:在子类与父类中实现同样函数名的方法,通过子类实例化对象,并调用该方法时,观察父类的方法是否被调用。
父类Record实现了_init_ 函数和 showrecode 方法。子类 GirlRecord 中实现了 showrecode 方法,没有实现_init_函数。在子类的 showrecode 方法中,调用了父类 showrecode 方法。
代码:
class Record: #定一个类 """A record class""" #定义该类的说明字符串 __Occupation = "scientist" #职业为科学家,私有变量 def __init__(self, name, age): #定义该类的初始化函数 self.name = name #将传入的参数值赋值给成员变量 self.age = age def showrecode(self): #定义一个成员函数 print("Occupation:",self.getOccupation() ) #该成员函数返回该类的成员变量 def getOccupation(self): #返回私有变量的方法 return self.__Occupation class GirlRecord(Record): #定一个类 """A GirlRecord class""" #定义该类的说明字符串 def showrecode(self): #定义一个成员函数 Record.showrecode(self) print("the girl:",self.name,"'s age is",self.age ) #该成员函数返回该类的成员变量 myc =GirlRecord ("Anna",42) myc.showrecode()运行结果:
3. super函数的功能
下面通过实例来演示父类方法被多次调用的情况方法被多次调用,以及如何使用suPer函数来避免父类的
创建相对复杂的继承关系类结构:
(l)创建一个父类,派生出两个子类,每个子类都需要调用父类的方法。
(2)创建一个孙子类,继承这两个子类。孙子类也需要调用其每个父类的方法。
创建相对复杂的继承关系类结构:
(l)创建一个父类,派生出两个子类,每个子类都需要调用父类的方法。
(2)创建一个孙子类,继承这两个子类。孙子类也需要调用其每个父类的方法。
在这里,将通过两个程序片段来演示实例描述的两种情况。
使用9.4.2小节中的直接调用父类方法,实现在多重继承中对父类方法的调用。
- 反面案例:直接调用父类,实现多重继承中的父类调用
使用9.4.2小节中的直接调用父类方法,实现在多重继承中对父类方法的调用。
例子中的类结构如下:
- 父类为 Record
- Record 派生的两个子类为 FemaleRecord 与 RetireRecord
- ThisRecord 继承于 FemaleRecord 与 RetireRecord
Record、FemaleRecord、RetireRecord 与 ThisRecord 这四个类都分别实现了各自的 showrecode 方法。具体如下:
- 孙子类 ThisRecord 的 showrecode 中,调用了其父类 FemaleRecord 与 RetireRecord 的 showrecode 方法。
- 子类 FemaleRecord 与 RetireRecord 的 showrecode 中,分别调用了其父类 Record 的 showrecode 方法
##反面例子########### class Record: #定一个类 """A record class""" #定义该类的说明字符串 __Occupation = "scientist" #职业为科学家,私有变量 def __init__(self, name, age): #定义该类的初始化函数 self.name = name #将传入的参数值赋值给成员变量 self.age = age def showrecode(self): #定义一个成员函数 print("Occupation:",self.getOccupation() ) #该成员函数返回该类的成员变量 def getOccupation(self): #返回私有变量的方法 return self.__Occupation class FemaleRecord(Record): #定一个类 """A GirlRecord class""" #定义该类的说明字符串 def showrecode(self): #定义一个成员函数 print(self.name,':',self.age,",female" ) #该成员函数返回该类的成员变量 Record.showrecode(self) class RetireRecord(Record): #定一个类 """A RetireRecord class""" #定义该类的说明字符串 def showrecode(self): #定义一个成员函数 Record.showrecode(self) print("retired worker" ) #该成员函数返回该类的成员变量 class ThisRecord(FemaleRecord,RetireRecord): #定一个类 """A ThisRecord class""" #定义该类的说明字符串 def showrecode(self): #定义一个成员函数 print("the member detail as follow:" ) #该成员函数返回该类的成员变量 FemaleRecord.showrecode(self) RetireRecord.showrecode(self) myc =ThisRecord ("Anna",62) myc.showrecode()运行结果:
- 正确案例:使用super函数,实现多重继承中的父类调用
##正面例子#################################### class Record: #定一个类 """A record class""" #定义该类的说明字符串 __Occupation = "scientist" #职业为科学家,私有变量 def __init__(self, name, age): #定义该类的初始化函数 self.name = name #将传入的参数值赋值给成员变量 self.age = age def showrecode(self): #定义一个成员函数 print("Occupation:",self.getOccupation() ) #该成员函数返回该类的成员变量 def getOccupation(self): #返回私有变量的方法 return self.__Occupation class FemaleRecord(Record): #定一个类 """A GirlRecord class""" #定义该类的说明字符串 def showrecode(self): #定义一个成员函数 print(self.name,':',self.age,",female" ) #该成员函数返回该类的成员变量 super().showrecode() class RetireRecord(Record): #定一个类 """A RetireRecord class""" #定义该类的说明字符串 def showrecode(self): #定义一个成员函数 super().showrecode() print("retired worker" ) #该成员函数返回该类的成员变量 class ThisRecord(FemaleRecord,RetireRecord): #定一个类 """A ThisRecord class""" #定义该类的说明字符串 def showrecode(self): #定义一个成员函数 print("the member detail as follow:" ) #该成员函数返回该类的成员变量 super().showrecode() myc =ThisRecord ("Anna",62) myc.showrecode()运行结果:
4. 使用***的方式实现RESTful API 接口
使用***的方式实现RESTful API的两种形式接口:静态接口与动态接口。静态接口指的是固定的URL;动态接口指的是带有参数的URL,类似GitHub的API会把参数放到URL的中间。
(l)实现静态接口:/status/allusers/list 接口。
(2)实现动态接口:/users/:user/info。其中,冒号后面的use:指代具体的参数。
#1 静态接口 class ChainURL(object): def __init__(self, attr=''): self._data = attr def __getattr__(self, attr): return ChainURL('%s/%s' % (self._data, attr)) def __str__(self): return self._data __repr__ = __str__ print(ChainURL().status.allusers.list)运行结果:
#2 动态接口 class ChainURL(object): def __init__(self, attr=''): self._data = attr def __getattr__(self, attr): return ChainURL('%s/%s' % (self._data, attr)) def __call__(self, attr): return ChainURL('%s/%s' % (self._data, attr)) def __str__(self): return self._data __repr__ = __str__ print(ChainURL().users('Anna').info)
运行结果: