py进阶

1/579文件IO文件介绍I/O流流的概念读写文件文件备份IO介绍大家应该听说过一句话:“好记性不如烂笔头”。不仅人的大脑会遗忘事情,计算机也会如此,比如一个程序在运行过程中用了九牛二虎之力终于计算出了结果,试想一下如果不把这些数据存放起来,相比重启电脑之后,“哭都没地方哭了”可见,在把数据存储起来有做么大的价值使用文件 的目的:就是把一些存储存放起来,可以让程序下一次执行的时候直接使用,而不必重新制作一份,省时省力文件文件是一些具有永久存储及特定顺序的字节组成的一个有序的、具有名称的集合。在各种介质上(可移动磁盘、硬盘、CD 等)存储的集合数据。通常情况下文件按照树状目录进行组织,每个文件都有文件名、文件所在路径、创建时间、访问权限等属性。流流提供了连续的字节流存储空间,虽然数据实际存储的位置可能不连续,甚至可以分布在多个磁盘上,但我们看到的是封装以后的数据结构,是连续的字节流抽象结构。除了和磁盘文件直接相关的文件流以外,流有多种类型,流可以分布在网络中,内存中或者是磁带中。换句话说,流是一组有序的,有起点和终点的字节集合, 是对计算机中数据传输的总称或者抽象即数据在两个设备间的传输称为流,流的本质是数据传输。2/57读取文件想一想:如果想用word编写一份简历,应该有哪些流程呢?打开word软件,新建一个word文件写入个人简历信息保存文件关闭word软件同样,在操作文件的整体过程与使用word编写一份简历的过程是很相似的打开文件新建立一个文件读/写数据关闭文件。在python,使用open函数,可以打开一个已经存在的文件,或者创建一个新文件 open(文件名,访问模式)示例如下: f = open('Python.txt', 'w')close( )示例如下:# 新建一个文件,文件名为:test.txtf = open('test.txt', 'w')# 关闭这个文件 f.close() # with open语句省略关闭with open('test.txt', 'w') as f:  f.read()使用read(num)可以从文件中读取数据,num表示要从文件中读取的数据的长度(单位是字节),如果没有传入num,那么就表示读取文件中所有的数据3/57f = open('python.txt', 'r')content = f.read(5)print(content)print("-"*30)content = f.read()print(content)f.close()注意:如果open是打开一个文件,那么可以不用写打开的模式,即只写 open('python.txt')就像read没有参数时一样,readlines可以按照行的方式把整个文件中的内容进行一次性读取,并且返回的是一个列表,其中每一行的数据为一个元素f = open('python.txt', 'r')content = f.readlines()print(type(content))i=1for temp in content: print("%d:%s"%(i, temp)) i+=1f.close()f = open('python.txt', 'r')content = f.readline()print("1:%s"%content)content = f.readline()print("2:%s"%content)f.close()open模式4/57写入文件写数据(write)使用write()可以完成向文件写入数据f = open('Test.txt', 'w')f.write('hello world, i am here!')f.close()注意:如果文件不存在那么创建,如果存在那么就先清空,然后写入数据复制文件5/57复制文件#导入os模块import os#原始路径,目标路径def Copy_Files(oriPath,endPath): #判断路径是否存在 endPathDir=os.path.dirname(endPath) if not os.path.exists(endPathDir): os.makedirs(endPathDir) #读取数据并写入数据 with open(oriPath,"rb") as fr: r=fr.read() with open(endPath,"wb") as fw: fw.write(r)下载文件模拟单线程下载文件6/57#导入os模块import os#oriPath源路径 endPath目标路径def Download_Files(oriPath,endPath): #判断路径存在 endPathDir=os.path.dirname(endPath) #不存在创建 if not os.path.exists(endPathDir): os.makedirs(endPathDir) #源文件大小 file_size=os.path.getsize(oriPath) #每次读取大小 readSize=1024 #读取总和 sumRead=0 #打开源文件和目标文件 fr=open(oriPath,"rb") fw = open(endPath, "wb") #循环读取 数据 while True: r = fr.read(readSize) #读到末尾结束 if r==b"": break else: sumRead+=readSize fw.write(r) print("%s文件已经下载了%0.2f%%"%(os.path.basename(oriPath),sumRead/file_size*100)) #清空缓存区,关闭流 fr.flush() fw.flush() fr.close() fw.close()Download_Files("E:\\颈椎操_超清.mp4","E:\\abc\\jzc.mp4")7/57序列化与反序列化Python序列化和反序列化通过将对象序列化可以将其存储在变量或者文件中,可以保存当时对象的状态,实现其生命周期的延长。并且需要时可以再次将这个对象读取出来。Python中有几个常用模块可实现这一功能。pickle模块示例:import pickle#字典序列化dic = {'age': 23, 'job': 'student'}byte_data = pickle.dumps(dic)# out -> b'\x80\x03}q\x00(X\x03\x00\x00\...'print(byte_data)#字典反序列化obj = pickle.loads(byte_data)print(obj)文件流序列化# 序列化with open('abc.txt', 'wb') as f: dic = {'age': 23, 'job': 'student'} pickle.dump(dic, f)# 反序列化with open('abc.txt', 'rb') as f: aa = pickle.load(f) print(aa) print(type(aa)) #json模块pickle可以很方便地序列化所有对象。不过json作为更为标8/57准的格式,具有更好的可读性(pickle是二进制数据)和跨平台性。是个不错的选择。json使用的四个函数名和pickle一致。import jsondic = {'age': 23, 'job': 'student'}dic_str = json.dumps(dic)print(type(dic_str), dic_str)# out:{"age": 23, "job": "student"}dic_obj = json.loads(dic_str)print(type(dic_obj), dic_obj)# out: {'age': 23, 'job': 'student'}

文件流序列化

import json

dic = {'age': 23, 'job': 'student'}

with open('abc.json', 'w', encoding='utf-8') as f:

json.dump(dic, f)

with open('abc.json', encoding='utf-8') as f:

obj = json.load(f)

print(obj)

总结

了解IO

文件流

读取文件

写入文件

复制文件

下载文件

序列化与反序列化

9/57

本章作业

模拟简单的博客

1.账号注册,登陆验证

2.写文章,包含【标题,作者,时间,内容】

3.查询文章,列出所有文章及时间

4.可查看其中一篇文章

5.删除文章

6.修改文章

7.退出系统

10面向对象

面向对象概念的学习

面向对象简介

对象都没有,还面向对象编程?

10/57

找到对象,面向她看程序就是面向对象?

11/57

这样才算面向对象编程嘛。

面向对象的概念

简单地说 面向对象编程(Object Oriented Programming)简称OOP 就是使我们分析、设计

和实现一个系统的方法尽可能地接近我们认识一个系统的方法。

描述对象之间的相互作用

面向对象的方法包括:

面向对象的分析(OOA, Object-Oriented Analysis)

面向对象的设计(OOD, Object-Oriented Design)

面向对象的程序设计(OOP, Object-Oriented Program)

面向对象技术主要围绕以下几个概念:

对象、抽象数据类型、类、类型层次(子类)、继承性、多态性。

面向对象VS面向过程

面向过程:

过程化设计先确定算法,再确定数据结构;面向过程的程序员习惯于建立数据结构存放数

据并定义方法(函数)来操作数据;

面向对象:

面向对象编程先确定数据结构,再确定算法;而面向对象程序员则构造对象模型,将数据

与方法组织在一起。

面向对象程序设计方法的优点

可重用性

可扩展性

可管理性

OOP的四个基本机制

抽象

封装

继承与派生

12/57

多态性

抽象

现实世界=>计算机世界

含义:对具体问题(对象)进行概括,抽出这一类对象的

公共性质并加以描述的过程。

要求:先注意问题的本质及描述,其次是实现过程或细

节。

所涉及到的主要内容:

数据抽象---描述某类对象的属性或状态(对象相互区别的

物理量);

代码抽象---描述某类对象的共有的行为特征或具有的功

能。

如何实现抽象:对问题进行分析,提取其属性和行为 。

抽象是有选择性的忽略:

决定什么是重要的,什么不是

聚焦并依赖于那些重要的

忽略那些不重要的

13/57

是描述对象的“基本原型”,它定义一类对象所能拥有的数 据和能完成的操作。

在面向对象的程序设计中,类是程序的基本单元。

相似的对象可以归并到同一个类中去,就像传统语言中的

变量与类型关系一样。

程序中的对象是类的一个实例,是一个软件单元,它由一

组结构化的数据和在其上的一组操作构成。

从程序设计的角度看,类是面向对象程序中最基本的程序单元,类实质上定义的是一种数

据类型,这种数据类型就是对象类型,我们可以使用类名称来声明对象变量

声明对象变量之后,还不能使用对象,必须创建对象实体之后,才能使用对象

狗类的设计

类名:狗(Dog)

属性:品种 、毛色、性别、名字、 腿儿的数量

方法(行为/功能):叫 、跑、咬人、吃、摇尾巴

14/57

对象

含义:它是具有该类类型的一个特定的个体,是类的一个

变量。

15/57

现实生活中对象指的是客观世界的实体;

程序中对象就是一组变量和相关方法的集合,其中变量表明对象的 状态,方法表明对象所

具有的行为。

16/57

奔驰汽车=类

奔驰smart=类

张三的那辆奔驰smart=对象

狗=类

大黄狗=类

李四家那只大黄狗=对象

水果=类

苹果=类

红苹果=类

红富士苹果=类

我嘴里吃了一半的苹果=对象

17/57

类的定义

定义一个类,格式如下:

18/57

class 类名:

方法列表

定义一个Car类:

# 定义类

class Car:

#属性

brand="玛莎拉蒂"

# 方法

def Move(self):

print("车正在移动...")

自行车:

数据(属性或者状态): 车架尺寸、 车轮尺寸、 牌子、

材料名称…

操作(方法或者功能): 变速、移动、 修理…

Windows窗口:

数据(属性或者状态): 颜色、 样式、 标题、 位置…

操作(方法或者功能): 打开窗口、 改变大小、 移动位

置…

类属性与方法

python中,可以根据已经定义的类去创建出一个个对象

创建对象的格式为:

对象名 = 类名()

19/57

创建对象demo:

# 定义类

class Car:

# 品牌

brand="玛莎拉蒂"

# 颜色

color="粉色"

# 轮子个数

wheelNum=8

# 方法

def GetCarInfo(self):

print('车轮子个数:%d, 颜色%s'%

(self.wheelNum, self.color))

# 移动

def move(self):

print('车在奔跑...')

# 鸣笛

def toot(self):

print("车在鸣笛...嘟嘟..")

#产生对象:

c=Car()

#调用对象方法

c.GetCarInfo()

#对象添加属性

c.carType="suv"

20/57

__init__魔法方法

构造魔法方法对象的实例化:

<类名>([<参数列表>])

将引用指向实例:

格式:变量名=<类名>([<参数列表>])

引用对象的成员变量和调用对象方法

对象.成员变量

对象.成员方法([参数列表])

对象的构造过程

1.为对象开辟空间;

2.调用魔法方法初始化;

3.返回对象的引用。

类是对象的模板,同一个类可以创建多个对象,每个对象

有各自的内存空间,不会互相影响。

构造魔法方法是一类特殊的成员方法,用于创建类的实例

并初始化对象。

声明构造魔法方法

def __init__(self):

21/57

语句块

注意:

系统为每个类提供一个默认的无参的构造魔法方法,但当

自行声明了构造魔法方法后,这个默认的无参构造方法不

再提供

构造构造方法无返回值

构造方法可以重载

构造魔法方法的格式:

def 类名:

#初始化函数,用来完成一些默认的设定

def __init__(self):

pass

# 定义汽车类

class Car:

def __init__(self, newWheelNum, newColor):

self.wheelNum = newWheelNum

self.color = newColor

def move(self):

print('车在跑,目标:夏威夷')

# 创建对象

BMW = Car(4, 'green')

print('车的颜色为:%s'%BMW.color)

print('车轮子数量为:%d'%BMW.wheelNum)

22/57

Self关键字用法

Self

所谓的self,可以理解为自己可以把self当做C++中类里面

的this指针一样理解,就是对象自身的意思某个对象调用

其方法时,python解释器会把这个对象作为第一个参数传

递给self,所以开发者只需要传递后面的参数即可

1.指代对象本身

2.访问当前对象的成员(区分同名的局部变量和成员变量)

__del__魔法方法

析构魔法方法声明为:

def __del__(self):

语句

一个类只有一个__del__方法,没有返回值。

程序中的对象有垃圾回收器(garbage collector)自动释

放,因此实际上__del__并不做释放托管资源的工作 而是

做非托管资源的释放工作,除非特殊需要,通常被省略。

对象传递

23/57

对象作为参数传递

实例:

“老张开车去东北.....”

定义一个人类, 属性:名字,年龄,性别

行为:开车,需要个车

定义一个汽车类,

属性:品牌,颜色,价格,轮子个数... 行为:驾驶,需要司机

#定义汽车

class Car:

def __init__(self,brand):

self.brand=brand

def BeDrive(self,p):

print(p.name+"正在开车"+self.brand)

#定义人

class People:

def __init__(self,name):

self.name=name

def Drive(self,c):

c.BeDrive(self)

c=Car("玛莎拉蒂")

p=People("老张")

#对象传递

p.Drive(c)

24/57

抽象练习题

1.创建一个学员类,并设计三个字段用于表示学生的成绩

(语文、数学、英语);然后定义一个列表list表示一个班

的学生(10人),依次输入每个学生的信息和成绩,输入

的同时将学员的每科成绩划分等级(100-90:A 89-80:

B 79-70:C 69-60:D 60以下:E)最后输出所有学员的

信息

2.编一个关于求多个某门功课总分和平均分的程序。

1.每个学生信息包括姓名和某门功课成绩。

2.假设5个学生。

3.类和对象的处理要合理

3.设计一个游戏角色类

字段:角色名、血量、魔法、状态

方法:释放技能 被伤害

要求:设计要合理

封装

访问级别:

完全公开: 变量名 方法名

私有 :__变量名 __方法名()

受保护 :_变量名 _方法名()

默认情况下,Python中的成员函数和成员变量都是公开的

25/57

(public),在python中没有类似public,private等关键词来修

饰成员函数和成员变量。

在python中定义私有变量只需要在变量名或函数名前加

上 ”__“两个下划线,那么这个函数或变量就是私有的了。

(1)_xxx "单下划线 " 开始的成员变量叫做保护变

量,意思是只有类实例和子类实例能访问到这些变量,

需通过类提供的接口进行访问;不能用'from module

import *'导入

(2)__xxx 类中的私有变量/方法名 (Python的函数

也是对象,所以成员方法称为成员变量也行得通。),

" 双下划线 " 开始的是私有成员,意思是只有类对象自己

能访问,连子类对象也不能访问到这个数据。

(3)__xxx__ 系统定义名字,前后均有一个“双下划线”

代表python里特殊方法专用的标识,如 __init__()代表

类的构造函数。

class Person:

name="Tony"

#私有属性

__age=18

__gender="男"

#私有方法

def __Method(self):

pass

26/57

在电子方面,封装是指把硅片上的电路管脚,用导线接引

到外部接头处,以便与其它器件连接。

在编程语言方面,封装即隐藏对象的属性和实现细节,仅对

外公开接口,控制在程序中属性的读和修改的访问级别;将

抽象得到的数据和行为(或功能)相结合,形成一个有机

的整体,也就是将数据与操作数据的源代码进行有机的结

合,形成“类”,其中数据和函数都是类的成员。

封装:行为和属性的结合

含义:提供将所抽象出的问题的属性(数据成员)和行为

(代码成员)相组合的一种机制,它能将这二类成员再组

合在一起,形成对象或实体。

目的:增强使用的安全性,使用者不必了解具体的实现细

节,而只需要通过设计者提供的外部接口来操作它。

优点:实现高度模块化,从而产生出软件构件(控件);

利用控件快速地组装程序。

客户可以调用一个并不了解内部机制的对象的方法

任何关于内部的改动对客户来说都是隐藏的

封装图解

27/57

封装定义程序如何引用对象的数据,封装实际上使用方法将类的数据隐藏起来,控制用户

对类的修改和访问数据的程度。

继承

28/57

继承的概念

继承是由已有的类创建新类的机制。

由继承得到的类称为子类(派生类),被继承的类称为父类

(超类)(基类)

继承的原则

子类继承父类的成员变量和成员方法

子类不继承父类的构造方法,能够继承父类的析构方法

子类不能删除父类的成员,但可以重定义父类成员

子类可以增加自己的成员

继承的作用

实现软件可重用的重要方式

增强软件可扩充性

提高软件的可维护性

面向对象中的两个重要概念:抽象和分类。

29/57

抽象和分类是人们认识世界的基本方法:

抽象是将现实世界中客观存在的事务映射到意识中的一种

方法。

分类是指确定这些抽象到意识中的概念之间的关系。

这些关系的基本形式包括一般到特殊和整体与局部。

在面向对象中,一般到特殊的关系用继承(Inheritance)表

示;整体与局部的关系用组合(composition)表示。

30/57

Pyhton中支持多继承

31/57

# 定义一个父类

class A:

def printA(self):

print('----A----')

# 定义一个父类

class B:

def printB(self):

print('----B----')

# 定义一个子类,继承自A、B

class C(A,B):

def printC(self):

print('----C----')

obj_C = C()

obj_C.printA()

obj_C.printB()

#运行结果:----A--------B----

Super()用法

super()用来引用当前对象的父类,用super()可以实现对

父类成员的访问。

访问父类被隐藏的成员变量,如:

super().variable

调用父类中被覆盖的方法,如:

super().Method([paramlist])

调用父类的构造函数,如:

super.__init__([paramlist])

注意:super()维系了整个继承关系

32/57

多态

什么是多态?

一个对象在不同的情况下,具有不同的形态,用于强类型

语言。是使用在继承和接口中实现。

Python中有两种说法:

1、python支持多态,python是一个弱类型,本身一个变 量名,可以存储任何类型的值,可以理解为多种形态

2、python不支持多态,多态本身是用于强类型语言的,

python是一个弱类型,所以不支持多态

多态:定义时的类型和运行时的类型不一样,此时就成为

多态

Python “鸭子类型”

在程序设计中,鸭子类型(英语:duck typing)是动态类

型的一种风格。

在这种风格中,一个对象有效的语义,不是由继承自特定

的类或实现特定的接口,而是由当前方法和属性的集合决

定。

这个概念的名字来源于由James Whitcomb Riley提出的鸭

子测试,“鸭子测试”可以这样表述:“当看到一只鸟走起来

像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟

就可以被称为鸭子。”

在鸭子类型中,关注的不是对象的类型本身,而是它是如

33/57

何使用的。

例如,在不使用鸭子类型的语言中,我们可以编写一个函

数,它接受一个类型为鸭的对象,并调用它的走和叫方

法。

在使用鸭子类型的语言中,这样的一个函数可以接受一个

任意类型的对象,并调用它的走和叫方法。

如果这些需要被调用的方法不存在,那么将引发一个运行

时错误。

任何拥有这样的正确的走和叫方法的对象都可被函数接受

的这种行为引出了以上表述,这种决定类型的方式因此得

名。

鸭子类型通常得益于不测试方法和函数中参数的类型,而

是依赖文档、清晰的代码和测试来确保正确使用。

从静态类型语言转向动态类型语言的用户通常试图添加一

些静态的(在运行之前的)类型检查,从而影响了鸭子类

型的益处和可伸缩性,并约束了语言的动态特性

python是一种弱类型语言,没有类型限制。变量的类型永 远是通过右侧的值判断的。方法中的参数,传递任何值都

行。但是要考虑方法内部的业务逻辑。

多态:

1、父类作为参数,可以传递父类和子类对象

2、接口作为参数,只能传递实现对象

34/57

所以有两种理解:

1、python不支持多态:python是弱类型,没有类型限 定,无法区分父和子,或者说接口和实现类

2、python处处是多态:python是弱类型,没有类型限 定,传递任何内容都行

多态的作用:

提高程序的扩展性

示例:

某枪战游戏中:

角色类:Role

属性:

血量

枪支库:考虑用什么类型存储

当前选择的枪支

方法:

更换枪支

开火

枪支类:

属性:

range射程

hurt伤害值

方法:

开火:Fire

手枪 类 PistolGun

来福枪类:RifleGun

35/57

激光枪:LaserGun

36/57

class Gun:

def __init__(self,name,range,hurt):

self.name=name

self.range = range

self.hurt = hurt

def __str__(self):

return "我是:"+self.name

def Fire(self):

print("枪-开火")

#手枪

class PistolGun(Gun):

def __init__(self, name,range,hurt):

super().__init__(name,range,hurt)

def __str__(self):

return super().__str__()

def Fire(self):

print("手枪开火。比u比u比u")

#来复枪

class RifleGun(Gun):

def __init__(self, name,range,hurt):

super().__init__(name,range,hurt)

def __str__(self):

return super().__str__()

def Fire(self):

print("来福枪开火。duang duang duang")

#激光枪

class LaserGun(Gun):

def __init__(self, name, range, hurt):

super().__init__(name, range, hurt)

def __str__(self):

return super().__str__()

37/57

def Fire(self):

print("激光枪-渍 渍 渍")

#角色

class Player:

def __init__(self,name,hp):

self.name=name

self.hp=hp

def __str__(self) -> str:

return "我是:"+self.name

class Role(Player):

def __init__(self, name, hp,guns):

super().__init__(name, hp)

self.guns=guns

self.currentGun=guns[0]

def __str__(self) -> str:

return super().__str__()

def Fire(self,g):

g.Fire()

def ChangeGun(self,num):

if num==0:

self.currentGun = self.guns[0]

elif num==1:

self.currentGun = self.guns[1]

else:

self.currentGun = self.guns[2]

p=PistolGun("手枪",100,100)

r=RifleGun("来复枪",100,1000)

l=LaserGun("激光枪",1000,1000)

38/57

guns=[p,r,l]

r=Role("police",100,guns)

r.ChangeGun(0)

print(r.currentGun)

r.Fire(r.currentGun)

实例属性,类属性/方法,静态方法

类属性

直接在类中定义的,与方法平齐,不在方法里的属性就是

类属性

实例属性

在方法里通过self.属性 都是实例属性

在了解了类基本的东西之后,下面看一下python中这几个

概念的区别先来谈一下类属性和实例属性

在前面的例子中我们接触到的就是实例属性(对象属性)

类属性就是类对象所拥有的属性,它被所有类对象的实例

对象所共有,在内存中只存在一个副本,这个和C++中类

的静态成员变量有点类似。

对于公有的类属性,在类外可以通过类对象和实例对象访

类方法

是类对象所拥有的方法,需要用修饰器@classmethod

39/57

(注解、元数据)来标识其为类方法,对于类方法,第一

个参数必须是类对象,一般以cls作为第一个参数(当然可

以用其他名称的变量作为其第一个参数,但是大部分人都

习惯以'cls'作为第一个参数的名字,就最好用'cls'了),能 够通过实例对象和类对象去访问。

静态方法

需要通过修饰器@staticmethod来进行修饰,静态方法不 需要多定义参数

从类方法和实例方法以及静态方法的定义形式就可以看出

来,

类方法的第一个参数是类对象cls,那么通过cls引用的必定

是类对象的属性和方法;

而实例方法的第一个参数是实例对象self,那么通过self引

用的可能是类属性、也有可能是实例属性(这个需要具体

分析),不过在存在相同名称的类属性和实例属性的情况

下,实例属性优先级更高。

静态方法中不需要额外定义参数,因此在静态方法中引用

类属性的话,必须通过类对象来引用

总结

方法是代码重用的重要手段

40/57

控制好代码被访问的程度 可以加强代码的安全性

封装、继承和多态是面向对象的基本特征

封装特性通过访问权限的设定将类的实现细节隐藏,提供

接口供外部访问

继承和组合是类间的基本关系,是软件复用的重要方法

多态是面向对象的重要标志

本章作业

1:创建一个圆Circle类,为该类提供两个方法,方法一用 于求圆的面积,方法二用于求圆的周长,同时为该类提供

一个变量r表示半径,一个变量PI表示圆周率。为该类提供

一个魔法方法,用于初始化属性的值

2:(1)创建Rectangle类,添加属性width、height;

(2)在Rectangle类中添加两种方法计算矩形的周长和面

积;(3)编程利用Rectangle输出一个矩形的周长和面积

3:饲养员类,动物类,食物类。实现饲养员给动物喂食

物。

4:创建一个账户Account类,该类有id:账户号

码,password:账户密码,name:真实姓名,personId:身份证

号码 字符串类型,email:客户的电子邮箱,balance:账户余

额.方法:deposit: 存款方法,参数是数字型的金

额;withdraw:取款方法,参数是数字型的金额.魔法方法:魔

法方法用于设置属性

5:某班有若干学生(学生对象放在一个List中),每个学生有 一个姓名属性、学号和考试成绩属性,某次考试结束后,

41/57

每个学生都获得了一个考试成绩。请求出本班的最高分,最

低分,总分以及平均分.

6:设计一个继承关系其中存在动物类Animal、狗类Dog和

猫类Cat,对于猫类和狗类都有一个吃eat方法,但是猫和狗

的吃eat方法的实现不同,请合理的设计出Animal Dog Cat

这3个类关系

7:设计一个形状类Shape,方法:求周长和求面积形状类的

子类:Rect(矩形),Circle(圆形) Rect类的子类:Square(正方

形)不同的子类会有不同的计算周长和面积的方法创建三个

不同的形状对象,放在列表里,分别打印出每个对象的周长

和面积

8:写出一个类People,并由该类做基类派生出子类

Employee和Teacher。其中People类具有name、age两个

保护成员变量,分别为String类型、整型,且具有公有的

GetAge成员函数,用于返回age变量的值。Employee类具

有保护成员变量empno,Teacher类有teacherNo成员变

量。

9:(1)设计一个User类,其中包括用户名、口令等属性 以及构造方法。获取和设置口令的方法,显示和修改用户

名的方法等。编写应用程序测试User类。

(2)定义一个student类,其中包括用户名、姓名、性别、

出生年月等属性以及Init()——初始化各属性、Display()

——显示各属性、Modify()——修改姓名等方法。实现并

测试这个类。

(3)从上题的student类中派生出Granduate(研究生)

类,添加属性:专业subject、导师adviser。重载相应的

42/57

成员方法。并测试这个类。

10.【基本题】定义一个Person类,它包含数据成员age,

name和gender。从Person中派生一个类Employee,在新类

中添加一个数据成员,存储个人的number.再从Employee

中派生一个类Executive,每个派生类都应该定义一个函

数,来显示相关的信息(名称和类型,如”Fred Smith is

an Employee”)。编写一个Main()函数,生成两个数组,

一个数组包含5个Executive对象,另一个数组包含5个一般

的Employee对象,然后显示它们的信息。另外,调用从

Employee类继承的成员函数,显示Executive信息。

11.【基本题】设计一个图书管理系统,基类为类Book,要求

有书名和作者属性, 由Book类派生子类AudioBook(有声

书,需要具有演说者属性),对于Book和AudioBook进行合

理的属性及行为的抽象,同时实现该类的控制台打印函数

12.某公司雇员(Employee)包括经理(Manager),技

术人员(Technician)和销售员(Salesman)。以

Employee类为基类派生出Manager,Technician和

Salesman类;Employee类的属性包括姓名、职工号、工

资级别,月薪(实发基本工资加业绩工资)。操作包括月

薪计算函数(Pay()),该函数要求输入请假天数,扣去应 扣工资后,得出实发基本工资。

Technician类派生的属性有每小时附加酬金和当月工作时

数,及研究完成进度系数。业绩工资为三者之积。也包括

同名的Pay()函数,工资总额为基本工资加业绩工资。

Salesman类派生的属性有当月销售额和酬金提取百分比,

业绩工资为两者之积。也包括同名的Pay()函数,工资总额

为基本工资加业绩工资。

43/57

Manager类派生属性有固定奖金额和业绩系数,业绩工资 为两者之积。工资总额也为基本工资加业绩工资。编程实

现工资管理。

可选题

项目名称:Bank Account Management System 银行账户

管理系统 简称BAM

练习1:(面向对象基础语法)

写一个账户类(Account),

属性: id:账户号码 长整数

password:账户密码

name:真实姓名

personId:身份证号码 字符串类型

email:客户的电子邮箱

balance:账户余额

方法: deposit: 存款方法,参数是float型的金额

withdraw:取款方法,参数是float型的金额

构造方法:

有参和无参,有参构造方法用于设置必要的属性

练习2:(封装)

将Account类作成完全封装,注意:要辨别每个属性的是否需

要公开

练习3:(继承,多态)

44/57

银行的客户分为两类,储蓄账户(SavingAccount)和信用账

户(CreditAccount),区别在于储蓄账户不允许透支,而信用

账户可以透支,并允许用户设置自己的透支额度.

注意:CreditAccount需要多一个属性 ceiling 透支额度

为这两种用户编写相关的类

同时要求编写Bank类,属性:

1.当前所有的账户对象的集合,存放在数组中

2.当前账户数量

方法:

1.用户开户,需要的参数:id,密码,密码确认,姓名,身份证号

码,邮箱,账户类型(int),返回新创建的Account对象

2.用户登录,参数:id,密码 返回Account对象,提示 用

s1.equals(s2)判断s1和s2两个字符串内容是否相等

3.用户存款,参数:id,存款数额,返回修改过的Account对象

4.用户取款,参数:id,取款数额,返回修改过的Account对象

5.设置透支额度 参数:id,新的额度 ,返回修改过的Account

对象.这个方法需要验证账户是否是信用账户

用户会通过调用Bank对象以上的方法来操作自己的账户, 请分析各个方法需要的参数

另外,请为Bank类添加几个统计方法

1.统计银行所有账户余额总数

2.统计所有信用账户透支额度总数

写个主方法测试你写的类

11异常

异常简介

什么是异常?

45/57

异常实际上是程序中错误导致中断了正常的指令流的一种

事件.

当Python检测到一个错误时,解释器就无法继续执行了,

反而出现了一些错误的提示,这就是所谓的"异常"

传统处理异常方法?

if...else...

正确异常处理

try:

语句

except :

语句

else:

语句

处理异常的优点:

综合上面的说法和传统的方法比较异常的优点:

1.把错误代码从常规代码中分离出来

2.把错误传播给调用堆栈

3. 按错误类型和错误差别分组

4. 系统提供了对于一些无法预测的错误的捕获和处理

5. 克服了传统方法的错误信息有限的问题

什么情况下使用例外机制?

1.当方法因为自身无法控制的原因而不能完成其任务

文件不存在,网络连接无法建立……

2.处理在方法、类库、类中抛出的例外

如FileInputStream.read产生IOException

46/57

3.在大的项目中采用统一的方式处理例外时

如编写一个文字处理器

4.例外应该是不经常发生但却可能发生的故障

一定发生的事件不应该用例外机制来处理

5.例外处理用于使系统从故障中恢复

提示信息/不产生无效的结果/释放资源

注意事项:

1.不同的例外处理策略

关键性应用(处理所有例外)

实验软件(可以忽略许多例外)

2.终止程序会导致资源泄漏,利用例外处理释放资源

3.尽可能近地处理例外,这样程序清晰易读

4.能在局部处理的错误不要使用例外机制

例外机制的处理比正常处理效率低

BaseException 所有异常的基类

SystemExit 解释器请求退出

KeyboardInterrupt 用户中断执行(通常是输入^C)

Exception 常规错误的基类

StopIteration 迭代器没有更多的值

GeneratorExit 生成器(generator)发生异常来通知退出

StandardError 所有的内建标准异常的基类

ArithmeticError 所有数值计算错误的基类

FloatingPointError 浮点计算错误

OverflowError 数值运算超出最大限制

ZeroDivisionError 除(或取模)零 (所有数据类型)

AssertionError 断言语句失败

AttributeError 对象没有这个属性

47/57

EOFError 没有内建输入,到达EOF 标记

EnvironmentError 操作系统错误的基类

IOError 输入/输出操作失败

OSError 操作系统错误

WindowsError 系统调用失败

ImportError 导入模块/对象失败

LookupError 无效数据查询的基类

IndexError 序列中没有此索引(index)

KeyError 映射中没有这个键

MemoryError 内存溢出错误(对于Python 解释器不是致

命的)

NameError 未声明/初始化对象 (没有属性)

UnboundLocalError 访问未初始化的本地变量

ReferenceError 弱引用(Weak reference)试图访问已经垃

圾回收了的对象

RuntimeError 一般的运行时错误

NotImplementedError 尚未实现的方法

SyntaxError Python 语法错误

IndentationError 缩进错误

TabError Tab 和空格混用

SystemError 一般的解释器系统错误

TypeError 对类型无效的操作

ValueError 传入无效的参数

UnicodeError Unicode 相关的错误

UnicodeDecodeError Unicode 解码时的错误

UnicodeEncodeError Unicode 编码时错误

UnicodeTranslateError Unicode 转换时错误

Warning 警告的基类

DeprecationWarning 关于被弃用的特征的警告

48/57

FutureWarning 关于构造将来语义会有改变的警告

OverflowWarning 旧的关于自动提升为长整型(long)的

警告

PendingDeprecationWarning 关于特性将会被废弃的警告

RuntimeWarning 可疑的运行时行为(runtime behavior) 的警告

SyntaxWarning 可疑的语法的警告

UserWarning 用户代码生成的警告

异常处理方式

捕获异常 try...except...

看如下示例:

try:

print('-----test--1---')

open('123.txt','r')

print('-----test--2---')

except IOError as resault:

print(resault)

说明:此程序看不到任何错误,因为用except 捕获到了IOError异常,并添加了处理的方法

pass 表示实现了相应的实现,但什么也不做;

print语句,会输出异常信息

49/57

咱们应该对else并不陌生,在if中,它的作用是当条件不满

足时执行的实行;同样在try...except...中也是如此,即如

果没有捕获到异常,那么就执行else中的事情

try:

#num = 100

print(num)

except NameError as errorMsg:

print('产生错误了:%s'%errorMsg)

else:

print('没有捕获到异常,真高兴')print('over...')

try...finally...语句用来表达这样的情况:

在程序中,如果一个段代码必须要执行,即无论异常是否

产生都要执行,那么此时就需要使用finally。 比如文件关

闭,释放锁,把数据库连接返还给连接池等

50/57

import time

try:

f = open('abc.txt')

try:

while True:

content = f.readline()

if len(content) == 0:

break

time.sleep(2)

print(content)

except:

#如果在读取文件的过程中,

#产生了异常,那么就会捕获到

#比如 按下了 ctrl+c

pass

finally:

f.close()

print('关闭文件')

except:

print("没有这个文件")

finally:

1.捕获例外的最后一步是通过finally语句为例外处理提

供一个统一的出口,使得在控制流程转到程序的其他部分

以前,能够对程序的状态作统一的管理。

2.无论try所指定的程序块中是否抛出例外,也无论

except语句的例外类型是否与所抛弃的例外的类型一致,

finally所指定的代码都要被执行,它提供了统一的出口。

3.通常在finally语句中可以进行资源的清除工作,如关 闭打开的文件、删除临时文件等。

finally和return的关系:

1.当try和except中有return时,finally仍然会执行;

2.finally是在return后面的表达式运算后执行的(此时并没

51/57

有返回运算后的值,而是先把要返回的值保存起来,不管

finally中的代码如何修改,返回的值都不会改变,仍然是

之前保存的值),所以函数返回值是在finally执行前确定

的;

3.finally中不可以有return,否则语法错误

练习捕捉异常

编写程序,包含四种异常

算术异常, 字符串越界,数组越界,格式异常(字符串转数字)

观察输出信息:

每个异常对象可以直接给出信息

抛出异常

raise ExceptionObj;

抛出异常: 不是出错产生,而是人为地抛出

1.任何从Exception派生的类都可以用raise语句抛出,抛出 例外用来表明程序遇到的错误无法正常执行而需要例外处

2.例外抛出点后的代码在抛出例外后不再执行

也可以说例外的抛出终止了代码段的执行

自定义异常

异常是一个类,用户定义的异常必须继承自Exception

52/57

'''自定义的异常类'''

class ShortInputException(Exception):

def __init__(self, length, atleast):

super().__init__()

self.length = length

self.atleast = atleast

def main()

try:

s = input('请输入 --> ')

if len(s) < 3:

#raise引发一个你定义的异常

raise ShortInputException(len(s), 3)

#x这个变量被绑定到了错误的实例

except ShortInputException as result:

print(result)

print('ShortInputException: 输入的长度是 %d,长度至少应是 %d'% (result.length,

result.atleast))

else:

print('没有异常发生.')

main()

总结

异常简介

异常处理方式

捕捉异常

抛出自定义异常

自定义异常

本章作业

作业一

自定义一个学生类,属性有 姓名 年龄,如果用户在给学

生年龄赋值时,年龄小于0抛出一个AgeLT0Exception,大

53/57

于150 抛出一个AgeGT150Exception

作业二

在定义银行类时,若取钱数大于余额则作为异常处理

(InsufficientFundsException).

思路:产生异常的条件是余额少于取额, 因此是否抛出异常

要判断条件

取钱是Withdrawal方法中定义的动作,因此在该方法中产生

异常.

处理异常安排在调用Withdrawal的时候,因此Withdrawal

方法要声明异常,由上级方法调用

要定义好自己的异常类

要求:捕捉到的异常对象内有余额和取额的信息

12自定义模块

自定义模块

Python许多时候自己定义的函数,需要经常调用时; 就可以自己定义一个模块,将常用函数写入模块里,下次

使用常用函数时直接导入模块,就可以使用函数了;

以下函数说明,函数功能:解决以.py脚本运行时和以.exe

运行时读取文件路径兼容性问题。

测试模块

python在执行一个文件时有个变量__name__可以根据

__name__变量的结果能够判断出,是直接执行的python 脚本还是被引入执行的,从而能够有选择性的执行测试代

码__name__如果写在被直接运行的主文件中,

54/57

是”__main__”如果写在被导入的文件中,运行主文件的时

候,导入文件中的__name__是”模块的名字”

__name__这个系统变量显示了当前模块执行过程中的名

称,如果当前程序运行在这个模块中,__name__ 的名称

就是__main__如果不是,则为这个模块的名称。

__main__一般作为函数的入口,类似于C语言,尤其在大 型工程中,常常有

if __name__ == "__main__"

:来表明整个工程开始运行的入口。

__all__设置

python模块中的__all__属性,

可用于模块导入时限制,如:

from module import *

此时被导入模块若定义了__all__属性,则只有__all__内

指定的属性、方法、类可被导入。

若没定义,则导入模块内的所有公有属性,方法和类 。

__all__展现了模块的内容大纲,而且也更清晰的提供了外 部访问接口。

如果一个文件中有__all__变量,那么也就意味着这个变量

中的元素,不会被from xxx import *时导入

55/57

通常包总是一个目录,可以使用import导入包,或者from

+ import来导入包中的部分模块。

包目录下为首的一个文件便是 __init__.py。然后是一些模

块文件和子目录,假如子目录中也有 __init__.py 那么它

就是这个包的子包了。

在创建许许多多模块后,我们可能希望将某些功能相近的

文件组织在同一文件夹下,这里就需要运用包的概念了。

包对应于文件夹,使用包的方式跟模块也类似,唯一需要

注意的是,当文件夹当作包使用时,文件夹需要包含

__init__.py文件,主要是为了避免将文件夹名当作普通的

字符串。__init__.py的内容可以为空,一般用来进行包的

某些初始化工作或者设置__all__值,__all__是在from

package-name import *这语句使用的,全部导出定义过

的模块。

可以从包中导入单独的模块。

1). import PackageA.SubPackageA.ModuleA,使用时必须

用全路径名

2). 变种: from PackageA.SubPackageA import ModuleA, 可以直接使用模块名而不用加上包前缀。

3). 也可以直接导入模块中的函数或变量:from

PackageA.SubPackageA.ModuleA import functionA

import语句语法:

1. 当使用from package import item时,item可以是

package的子模块或子包,或是其他的定义在包中的名字

(比如一个函数、类或变量) 首先检查item是否定义在

56/57

包中,不过没找到,就认为item是一个模块并尝试加载

它,失败时会抛出一个ImportError异常。

2. 当使用import item.subitem.subsubitem语法时,最后

一个item之前的item必须是包,最后一个item可以是一个

模块或包,但不能是类、函数和变量

3. from pacakge import * 如果包的__init__.py定义了一

个名为__all__的列表变量,它包含的模块名字的列表将作

为被导入的模块列表。 如果没有定义__all__, 这条语

句不会导入所有的package的子模块,它只保证包

package被导入,然后导入定义在包中的所有名字。

python包是:

包是一个有层次的文件目录结构,它定义了由n个模块或n

个子包组成的python应用程序执行环境。

通俗一点:包是一个包含__init__.py 文件的目录,该目录

下一定得有这个__init__.py文件和其它模块或子包。

包将有联系的模块组织在一起,即放到同一个文件夹下,

并且在这个文件夹创建一个名字为__init__.py 文件,那么 这个文件夹就称之为包有效避免模块名称冲突问题,让应

用组织结构更加清晰

__init__.py 控制着包的导入行为

__init__.py为空仅仅是把这个包导入,不会导入包中的模

__all__在__init__.py文件中,定义一个__all__变量,它

控制着 from 包名 import *时导入的模块

总结

57/57

自定义模块

自定义包及__init__.py的意义

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,390评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,821评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,632评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,170评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,033评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,098评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,511评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,204评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,479评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,572评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,341评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,893评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,171评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,486评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,676评论 2 335

推荐阅读更多精彩内容

  • 这是16年5月份编辑的一份比较杂乱适合自己观看的学习记录文档,今天18年5月份再次想写文章,发现简书还为我保存起的...
    Jenaral阅读 2,707评论 2 9
  • Python 面向对象Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对...
    顺毛阅读 4,203评论 4 16
  • 1、男人最光彩的一面,在于他冒险之后的成功。 2、一个人在一生会做很多事,到头来让自己满意的不会太多,往往是因为太...
    一笑人生阅读 400评论 1 5
  • 毕业近两年的时间里,我有幸辗转于北京和上海两个大城市,体验了在北上的租房生活。苦吗?苦!但是不曾后悔过! (一) ...
    琴音如风阅读 424评论 0 0
  • 1、老公:“依我的见解,哥伦布绝对没老婆。不然,他什么大陆也发现不了。” 老婆:“ 为什么这么想?” 老公:“...
    军会让离别阅读 188评论 0 1