1 面向对象程序设计

1.1 知识点思维导图

1.1.1 面向对象概述思维导图

image.png

1.1.2 类和对象的定义思维导图

image.png

1.1.3 魔术方法的思维导图

image.png

1.1.4 私有成员与封装

image.png

1.1.5 类的继承

image.png

1.1.6 类的多态特性

image.png

1.1.7 类的属性和实例属性

image.png

1.2 练习题

1.2.1 基础知识练习题

1.下列说法中不正确的是( D )。
A.类是对象的模板,而对象是类的实例
B.实例属性名如果以 开头,就变成了一个私有变量
C.只有在类的内部才可以访问类的私有变量,外部不能访问
D.在Python中,一个子类只能有一个父类
2.下列选项中不是面向对象程序设计基本特征的是( C )。
A.继承 B.多态 C.可维护性 D.封装
3.在方法定义中,访问实例属性x的格式是( )。B
A.x B.self.x C.self[x] D.self.getx()
4. 在面向对象开发中,由类创建的实例,我们称之为( A )
A. 对象 B.变量 C.方法 D.函数

  1. 下列程序的执行结果是( D )。

    1. class Point:
    2. x=10
    3. y=10
    4. def __init__(self,x,y):
    5. self.x=x
    6. self.y=y
    7. pt=Point(20,20)
    8. print(pt.x,pt.y)

    A.10 20 B.20 10 C.10 10 D.20 20
    6.下列程序的执行结果是( A )。

    1. class C():
    2. f=10
    3. class C1(C):
    4. pass
    5. print(C.f,C1.f)

    A.10 10 B.10 pass C.pass 10 D.运行出错

  2. 现有如下代码, 会输出什么: D

    1. class People(object):
    2. __name = "heima"
    3. __age = 18
    4. p1 = People()
    5. print(p1.__name, p1.__age)

    A.heima 18
    B.heima18
    C.”heima”18
    D. 程序错误,得不到输出
    8.在Python中,定义类的关键字是 。class
    9.类的定义如下:

    1. class person:
    2. name='Liming'
    3. score=90

    该类的类名是 person ,其中定义了 name 属性和 scroe 属性,它们都是 类的 属性。如果在属性名前加两个下划线(__),则属性是 私有 属性。将该类实例化创建对象p,使用的语句为 p=person() ,通过p来访问属性,格式为 p.name 、 p.score 。

10.Python类的构造方法是 init() ,它在 创建 对象时被调用,可以用来进行一些属性 初始化 操作;类的析构方法是 del() , 它在 销毁 对象时调用,可以进行一些释放资源的操作。

11.可以从现有的类来定义新的类,这称为类的 继承 ,新的类称为 子类 ,而原来的类称为 基类 、父类或超类。

12.创建对象后,可以使用 . 运算符来调用其成员。
13.下列程序的运行结果为 100

  1. class Account:
  2. def __init__(self,id):
  3. self.id=id
  4. id=888
  5. acc=Account(100)
  6. print(acc.id)

14.下列程序的运行结果为 100,100 。

  1. class parent:
  2. def __init__(self,param):
  3. self.v1=param
  4. class child(parent):
  5. def __init__(self,param):
  6. parent.__init__(self,param)
  7. #super().__init__(param)
  8. self.v2=param
  9. obj=child(100)
  10. print(obj.v1,obj.v2)
  1. 下列程序的运行结果为 。
    1. class account: #银行账户
    2. def __init__(self,id,balance):
    3. self.id=id #账户名
    4. self.balance=balance #余额
    5. def deposit(self,amount): #存款方法
    6. self.balance+=amount
    7. def withdraw(self,amount): #取款方法
    8. self.balance-=amount
    9. acc1=account('1234',100)
    10. acc1.deposit(500)
    11. acc1.withdraw(200)
    12. print(acc1.balance)
  2. 什么是类,什么是对象?
    类:对一类事物的描述,是抽象的、概念上的定义。
    对象:实际存在的该类事物的每个个体,因而也称实例(instance)。
    类是对象的抽象,对象是类的实例。
    17. python中如何定义一个类的格式 :::info class 类名(object):
    成员(方法) :::
  3. 类(class)由哪三个部分构成
    类名,属性,方法。
    19. 类名的命名规则是什么
    要遵循标识符的命名规范,尽量使用大驼峰命名法,命名时做到“见名思意”。
    20 . python中如何通过类创建对象 :::info 对象名 = 类名() ::: 21 定义类如下:

    1. class Hello(object):
    2. pass

    下面说明错误的是( D )。
    A. 该类实例中包含dir()方法
    B. 该类实例中包含hash()方法
    C. 该类实例中包含dir(),还包含hash()
    D. 该类没有定义任何方法,所以该实例中没有包含任何方法
    22. 定义类如下: B

    1. class Hello():
    2. def showInfo(self):
    3. print(self.x)

    下面描述正确的是( )。
    A. 这个类的语法有问题
    B. 该类可以实例化
    C. 在pycharm工具中会出现语法错误,说self没有定义
    D. 该类可以实例化,并且能正常通过对象调用showInfo()
    23. 关于Python类说法正确的是( C )。
    A. 类的实例方法必须创建对象后才可以调用
    B. 类的实例方法必须创建对象前才可以调用
    C. 类的类方法可以用对象和类名来调用
    D. 类的静态属性可以用类名和对象来调用
    24. 定义类如下: C

    1. class Hello(object):
    2. def __init__(self,name)
    3. self.name=name
    4. def showInfo(self)
    5. print(self.name)

    下面代码能正常执行的( )。
    A. h = Hello
    h.showInfo()
    B. h = Hello()
    h.showInfo(“张三”)
    C. h = Hello(“张三”)
    h.showInfo()
    D. h = Hello(“admin”)
    showInfo
    25. 定义类如下:

    1. class A():
    2. def a():
    3. print("a")
    4. class B ():
    5. def b():
    6. print("b")
    7. class C():
    8. def c():
    9. print(c)
    10. class D(A,C):
    11. def d():
    12. print("d")

    以下程序能执行的结果是( )。 :::info d=D()
    d.a()
    d.c()
    d.d() ::: A. a,c,d B. a,d
    C. d,a D. 执行会报错
    26. init方法有什么作用,如何定义
    init方法用来监听对象的实例化过程。
    def init(self):
    pass
    27. str方法有什么作用,使用时应注意什么问题
    str方法用来追踪对象的属性值的变化的。
    str方法不能再添加任何参数,
    str方法必须有一个返回值,返回值必须为字符串类型。
    28. 对象方法中的”self”代表什么
    self代表的是类的实例对象(注意不是类本身)
    29.要修改一个对象的属性有几种方法,分别是什么?
    直接修改属性的值。
    通过方法修改属性的值。
    通过方法对属性的值进行递增/减。
    30. 保护属性安全性的一般处理方式是什么?
    把这个属性设置为私有的,通过一些封装的方法进行操作。
    31. 要想将一个属性私有化,该怎么做?
    在属性名前面加上两个下划线,即:属性名。
    32. 如何将上述的name改成私有属性
    self.
    name = name
    33. 如果子类中没有定义init方法,但是要实例化一个对象,那此时会自动调用父类的构造方法吗?
    如果本身没有定义init方法,会调用直接继承给它的第一个父类的init方法。
    34. 简单描述什么是单继承
    一个子类只能有一个父类,被称为单继承。
    35. 如果子类重写了init方法,那么在实例化对象的时候,你觉得会调用哪个构造方法,是父类的还是子类的?
    子类重写了init方法,默认会调用自己的。
    36. 当子类重写init方法,在实例化对象的时候,如果想要调用父类的init方法该怎么办?
    需要显示进行调用,即:super().init()。
    37. 在一个对象销毁的时候,可以在什么函数释放资源?
    通过魔法方法,del
    38. 简单描述什么是多继承
    一个子类可以有多个父类,称为多继承。
    39. 简单描述什么是重写?
    子类不想原封不动地继承父类的方法,而是想作一定的修改,这就需要采用方法的重写。方法重写又称方法覆盖。
    40 . 学过Python面向对象的知识,应该都知道魔法方法,下面请你来说说new()和init()的区别?
    (1)new()是一个静态方法,而init()是一个实例方法;
    (2)new()方法会返回一个创建的实例,而init()什么都不返回;
    (3)只有在new()返回一个cls的实例时后面的init()才能被调用;
    (4)当创建一个新实例时调用new(),初始化一个实例时用init()。

    1.2.2 程序设计题

    1.定义一个Person类,提供可以重新设置私有属性name的方法,限制条件为字符串长度小于10,才可以修改。

    1. # Person类
    2. class Person(object):
    3. def __init__(self):
    4. self.__name = ""
    5. def set_name(self, name):
    6. if len(name) < 10:
    7. self.__name = name

    1.设计一个Circle类来表示园,这个类包含圆的半径以及求周长和面积的函数。再使用这个类创建半径为1~100的圆,并计算出相应的周长及面积。

    1. class circle:
    2. def __init__(self,radius):
    3. self.radius=radius
    4. def length(self):
    5. return self.radius*2*3.14
    6. def area(self):
    7. return self.radius**2*3.14
    8. a=int(input("输入半径:"))
    9. c=circle(a)
    10. print("周长为:",c.length(),"面积为:",c.area())

    2.编写程序并测试,有一个汽车类Vehicle,类中的私有数据成员为车轮个数wheels和车重weight;小车类Car是汽车类vehicle派生类,其中包含载客人数passenger_load,默认4人;卡车类Truck是汽车类vehicle派生类,其中包含载客人数passenger_load和载重量payload。
    提示:编写类时要使用get和set方法,Vehicle类定义display()显示车轮和重量,Car和Truck中要对display()进行同名覆盖。

    1. class Vehicle:
    2. def __init__(self,wheels,weight):
    3. self.setWheels(wheels)
    4. self.setWeight(weight)
    5. def setWheels(self,wheels):
    6. self.__wheels = wheels
    7. def setWeight(self,weight):
    8. self.__weight = weight
    9. def getWheels(self):
    10. return self.__wheels
    11. def getWeight(self):
    12. return self.__weight
    13. def display(self):
    14. print("车轮={0},重量={1}".format(self.getWheels(),self.getWeight()))
    15. class Car(Vehicle):
    16. def __init__(self,wheels,weight,passenger_load = 4):
    17. super(Car,self).__init__(wheels,weight)
    18. self.setPassenger(passenger_load)
    19. def setPassenger(self, passenger_load,):
    20. self.__passenger_load = passenger_load
    21. def getPassenger(self):
    22. return self.__passenger_load
    23. def display(self):
    24. print("车轮={0},重量={1},载客人数={2}".format(self.getWheels(),self.getWeight(),self.getPassenger()))
    25. class Truck(Vehicle):
    26. def __init__(self,wheels,weight,passenger_load,payload):
    27. super(Truck, self).__init__(wheels,weight)
    28. self.setPassenger(passenger_load)
    29. self.setPayload(payload)
    30. def setPassenger(self,passenger_load):
    31. self.__passenger_load = passenger_load
    32. def setPayload(self,payload):
    33. self.__payload = payload
    34. def getPassenger(self):
    35. return self.__passenger_load
    36. def getPayload(self):
    37. return self.__payload
    38. def display(self):
    39. print("车轮={0},重量={1},载客数={2},载重量={3}".format(self.getWheels(),self.getWeight(),self.getPassenger(),self.getPayload()))
    40. vehicle = Vehicle(4,10000)
    41. vehicle.display()
    42. car = Car(4,5000,4)
    43. car.display()
    44. truck = Truck(8,20000,12,12000)
    45. truck.display()

    3.编写一个学生和教师数据输入和输出的程序。学生数据包括编号、姓名、班号、和成绩;教师的数据含有编号、姓名、职称和部门。要求设计一个person类,作为学生数据操作类student和教师数据操作类teacher的基类。

    1. class Person(object):
    2. def __init__(self,number,name):
    3. self.setNumber(number)
    4. self.setName(name)
    5. def setNumber(self,number):
    6. self.__number=number
    7. def setName(self,name):
    8. self.__name=name
    9. def getName(self):
    10. return self.__name
    11. def getNumber(self):
    12. return self.__number
    13. def show(self):
    14. print("编号为:"+str(self.getNumber())+",名字为:"+str(self.getName()))
    15. class Student(Person):
    16. def __init__(self,number,name,classNumber,grade):
    17. super(Student,self).__init__(number,name)
    18. Person.__init__(self,number,name)
    19. self.setClassNumber(classNumber)
    20. self.setGrade(grade)
    21. def setClassNumber(self,classNumber):
    22. self.__classNumber=classNumber
    23. def setGrade(self,grade):
    24. self.__grade=grade
    25. def getClassNumber(self):
    26. return self.__classNumber
    27. def getGrade(self):
    28. return self.__grade
    29. def show(self):
    30. super(Student,self).show()
    31. print("学生班号为:"+str(self.getClassNumber())+",成绩为:"+str(self.getGrade()))
    32. class Teacher(Person):
    33. def __init__(self,number,name,title,department):
    34. super(Teacher,self).__init__(number,name)
    35. Person.__init__(self,number,name)
    36. self.setTitle(title)
    37. self.setDepartment(department)
    38. def setDepartment(self,department):
    39. self.__department=department
    40. def setTitle(self,title):
    41. self.__title=title
    42. def getTitle(self):
    43. return self.__title
    44. def getDepartment(self):
    45. return self.__department
    46. def show(self):
    47. super(Teacher,self).show()
    48. print("教师职称是:"+str(self.getTitle())+",教师部门是:"+str(self.getDepartment()))
    49. if __name__=='__main__':
    50. hexiaojiang=Person(20181611701,'He xiao jiang')
    51. hexiaojiang.show()
    52. studentWang=Student(20181611750,'Wang hao jia',8,100)
    53. studentWang.show()
    54. teacherNa=Teacher(520521,'Nasinhore','讲师','教学部')
    55. teacherNa.show()

    4.定义一个水果类,然后通过水果类,创建苹果对象、橘子对象、西瓜对象并分别添加上颜色属性 ```python

    水果类

    class Fruits(object): pass

苹果对象

apple = Fruits() apple.color = “red”

橘子对象

tangerine = Fruits() tangerine.color = “orange”

西瓜对象

watermelon = Fruits() watermelon.color = “green”

  1. <a name="bGzTx"></a>
  2. # 2 模块与包
  3. <a name="VVhFn"></a>
  4. ## 2.1 知识点思维导图
  5. <a name="VhXtI"></a>
  6. ### 2.1.1 模块
  7. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/28265088/1654701023243-7559a77b-ca3a-4519-9de1-40f8feb64af6.png#clientId=ud0d46005-df3b-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=302&id=eYIHI&margin=%5Bobject%20Object%5D&name=image.png&originHeight=275&originWidth=786&originalType=binary&ratio=1&rotation=0&showTitle=false&size=120451&status=done&style=none&taskId=u9bc874e2-869d-42b3-b049-93bc2fd2306&title=&width=864)
  8. <a name="RskpH"></a>
  9. ### 2.1.2 包
  10. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/28265088/1654701062622-d98a5ccf-4b46-4c4e-83ab-32e14f964a56.png#clientId=ud0d46005-df3b-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=321&id=kwbFX&margin=%5Bobject%20Object%5D&name=image.png&originHeight=262&originWidth=624&originalType=binary&ratio=1&rotation=0&showTitle=false&size=119292&status=done&style=none&taskId=u8d9be519-5e5b-44d6-9388-58c1fed41eb&title=&width=764)
  11. <a name="lXLJ7"></a>
  12. ## 2.2 练习题
  13. <a name="Us769"></a>
  14. ### 2.2.1 基础知识练习题
  15. 1.以下导入模块方式中错误的是( )<br />A. import mo # mo.函数名( ) mo.类名( ) mo.变量名<br />B. from mo import * <br />C. import mo as moo # moo.函数名( ) moo.类名( ) moo.变量名<br />D.import * from mo #语法错误<br />2.对于以下导入方式中使用模块math中的sqrt函数正确的方式是( C )
  16. ```python
  17. import math as mymath

A. math.sqrt(3)
B. sqrt(3)
C. mymath.sqrt(3)
D.math.mymath.sqrt(3)
3.以下关于模块的说法错误的是( C )
A. 模块就是一个普通的Python程序文件
B.任何一个普通的Python程序文件可以作为模块导入
C.模块文件的扩展名可以是txt
D.Python 运行时只会从指定的目录中搜索导入的模块
4.以下对包的说法错误的是( A )
A.包可以是一个任何目录 (directory,(文件夹 , floder))
B.包可以是嵌套的
C.作为包中的目录要包含特殊的 __init .py文件
D.包目录中的
init__.py文件内容可以为空
5.以下关于包和模块的说法错误的是( B )
A.包中可以包含模块
B.模块中可以包含包
C.一般在小规模的项目中使用模块就行了
D.包一般需要在大、中规模的项目中使用
6. 以下关于模块说法错误的是( C )。
A. 一个xx.py就是一个模块
B. 任何一个普通的xx.py文件可以作为模块导入
C. 模块文件的扩展名不一定是 .py
D. 运行时会从指定的目录搜索导入的模块,如果没有,会报错异常
7.在Python中要生成随机数,应该使用( B )
A:math 模块
B:random模块
C:numpy 模块
D:pygame 模块

  1. 什么是包

从物理上看,包就是一个文件夹,在该文件夹下包含了一个init.py文件
从逻辑上看,包的本质依然是模块
包的作用是包含多个模块,但包的本质依然是模块,因此包也可用于包含包

  1. 怎样定义包

创建一个文件夹,该文件夹的名称就是该包的包名
在该文件夹内添加一个init.py文件
10. 包的作用是什么?
该函数包含对外层函数作用域的引用
11. init.py文件有什么用?
将文件夹变为Python包
12. 使用相对导入时的注意事项
相对导入不能在执行文件中使用,相对导入只能在被导入的模块中使用。
13. 模块的搜索顺序
先从内存中找,再从内置中找,sys.path中找
14.os和sys模块的作用?
os经常要查找操作文件,读取配置文件信息
Sys提供对解释器使用或维护的一些变量的访问,以及与解释器的交互函数。
15. 如何生成一个随机数?
random.randint()

2.2.2 程序设计练习题

1.编写程序,计算三维坐标中的点x = (5, 6, 7)和y = (8, 9, 9)之间的距离。
x(x1,y1,z1) y=(x2,y2,z2)
dist=sqrt( (x2-x1)^2+(y2-y1)^2+(z2-z1)^2 )

  1. import math
  2. x = (5, 6, 7)
  3. y = (8, 9, 9)
  4. distance = math.sqrt(sum([(a - b) ** 2 for a, b in zip(x, y)]))
  1. def distance(x, y):
  2. import math
  3. d = (x[0] - y[0]) ** 2 + (x[1] - y[1]) ** 2 + (x[2] - y[2]) ** 2
  4. return round(math.sqrt(d), 2)
  5. a = (5, 6, 7)
  6. b = (8, 9, 9)
  7. d = distance(a, b)
  8. print(d)

2.编写程序,计算正整数的阶乘,并将阶乘的结果中各个数字相加,最后得到其和。例如,6!= 720,7+2+0=9。

  1. import math
  2. n=input("n=")
  3. result=math.factorial(int(n)) #math.factorial()用于计算n的阶乘
  4. print(result)
  5. sum=0
  6. for i in str(result):
  7. sum=sum+int(i)
  8. # while result != 0:
  9. # print("result=",result)
  10. # i=result % 10
  11. # sum=sum+i
  12. # print("i=",i)
  13. # print("sum=",sum)
  14. # result=result // 10
  15. print("sum=",sum)
  1. import math
  2. def compute(n):
  3. n = math.factorial(n)
  4. ans = sum(int(c) for c in str(n))
  5. return ans
  1. def fac_sum(n):
  2. from functools import reduce
  3. s2 = str(reduce(lambda x, y: x*y, range(1, n+1)))
  4. sums = 0
  5. for i in s2:
  6. sums = sums + int(i)
  7. print(sums)
  8. fac_sum(6)

3.在 package_test目录下创建 test1.py、test2.py、init.py 文件,test.py 为测试调用包的代码,然后在 package_test 同级目录下创建 test.py文件并调用 package_test包。

  1. A=999
  2. B=777
  3. def fun():
  4. print("fun is invoked.")
  1. class X(object):
  2. def __init__(self):
  3. print("Object of class X is created.")
  1. import package_test.test1
  2. import package_test.test2
  3. print(package_test.test1.A)
  4. print(package_test.test1.B)
  5. package_test.test1.fun()
  6. obj=package_test.test2.X()

3 异常处理

3.1 知识点思维导图

image.png

3.2 练习题

3.2.1 基础知识练习题

1.python中用来手动抛出异常的关键字是( C )
A.try B.except C.raise D.finally
2.( C )类是所有异常类的父类
A.Throwable B.Error C.Exception D.BaseException
3.对于except字句的排列,下列哪种是正确的( B )
A.父类在先,子类在后
B.子类在先,父类在后
C.没有顺序,谁在前谁先捕获
D.先有子类,其他如何排列都无关
4.在异常处理中,如释放资源、关闭文件、关闭数据库等由( C )来完成。
A.try字句 B.except子句 C.finally字句 D.raise子句
5.当方法遇到异常又不知如何处理时,下列哪种说法是正确的( B )
A.捕获异常 B.抛出异常 C.声明异常 D.嵌套异常
6. 以下哪项Python能正常启动( D )。
A. 拼写错误 B. 错误表达式 C. 缩进错误 D. 手动抛出异常
7. 有关异常说法正确的是( B )。
A. 程序中抛出异常终止程序
B. 程序中抛出异常不一定终止程序
C. 拼写错误会导致程序终止
D. 缩进错误会导致程序终止
8. 对以下程序描述错误的是( A )。

  1. try:
  2. # 语句块1
  3. except IndexError as i:
  4. # 语句块2

A. 该程序对异常处理了,因此一定不会终止程序
B.该程序对异常处理了,不一定不会因异常引发终止
C. 语句块1,如果抛出IndexError 异常,不会因为异常终止程序
D. 语句块2 不一定会执行
9. 程序如下:

  1. try:
  2. number = int(input("请输入数字:"))
  3. print("number:",number)
  4. print("=======hello======")
  5. except Exception as e:
  6. # 报错错误日志
  7. print("打印异常详情信息: ",e)
  8. else:
  9. print("没有异常")
  10. finally:
  11. # 关闭资源
  12. print("finally")
  13. print("end")

输入的是 结果是:( )。
A. number: 1
打印异常详情信息: invalid literal for int() with base 10:
finally
end
B. 打印异常详情信息: invalid literal for int() with base 10:
finally
end
C. ========hello===========
打印异常详情信息: invalid literal for int() with base 10:
finally
end
D. 以上都正确
10.异常和错误有什么区别?
异常是指因为程序执行过程中出错而在正常控制流以外采取的行为。严格来说,语法错误和逻辑错误不属于异常,但有些语法错误往往会导致异常,例如由于大小写拼写错误而访问不存在的对象,或者试图访问不存在的文件,等等。

3.2.2 程序设计练习题

1.定义input_password函数,提示用户输入密码.如果用户输入长度<8,抛出异常。如果用户输入长度>=8,返回输入的密码

  1. def input_password():
  2. while True:
  3. password=input('请输入密码')
  4. try:
  5. if len(password)>8:
  6. raise Exception("len too long!")
  7. else:
  8. pass
  9. finally:
  10. print('执行一次')
  11. print(input_password())

2.定义一个异常类 OverNumberError ,当用户输入数字大于 100 时,抛出异常内容 “输入数字过大!”

  1. class OverNumberError(Exception):
  2. def __init__(self):
  3. super(Exception, self).__init__()
  4. def __str__(self):
  5. return "输入数字过大!"
  6. try:
  7. user_input = input("输入一个数字:")
  8. if int(user_input) > 100:
  9. raise OverNumberError()
  10. except OverNumberError as e:
  11. print(e)

3.编写一个计算减法的方法,当第一个数小于第二个数时,抛出“被减数不能小于减数”的异常

  1. def jianfa(a, b): # 定义一个函数
  2. try: # 尝试
  3. if a < b: # 如果a小于b
  4. raise BaseException('被减数{}不能小于减数{}'.format(b,a))
  5. else: #否则
  6. print(a - b) # 输出a-b
  7. except BaseException as f : #
  8. print(f) # 触发,抛出异常
  9. jianfa(4,5) # 第一个数4,第二个数是5

4.简单使用异常处理,输入两个数a,b , 其中b必须为零,进行a/b的算式,让你的程序抛出“被除数不能为零”的异常。

  1. try:
  2. x = int(input('请输入第一个数'))
  3. y = int(input('请输入第二个数字'))
  4. print(x / y)
  5. y = x + '5'
  6. print(x)
  7. s = input('输入一个数')
  8. except (ZeroDivisionError,TypeError) as e:
  9. print(e)

5.编写一个计算减法的方法,自己输入两个数,当第一个数小于第二个数时,抛出“被减数不能小于减数”的异常。

  1. def jianfa(a,b):
  2. if a<b:
  3. raise BaseException('被减数不能小于减数')
  4. #return 0
  5. else:
  6. return a-b
  7. try:
  8. a=int(input())
  9. b=int(input())
  10. print(jianfa(a, b))
  11. print("没遇到自己定义的错误") #不打印
  12. except:
  13. print("被减数不能小于减数")
  14. finally:
  15. print("OK")

6.使用异常处理try … except… 打开一个不存在的文件。

  1. try:
  2. with open('non_exist.txt',mode='r') as f1:
  3. print('file opend!')
  4. f1.close()
  5. except:
  6. print('file is not exist!')
  7. print('DONE!')

8.运算a/b,先判断b是不是等于零,如果b等于零,抛出分母为零异常。

  1. def yunsuan(a,b):
  2. if b==0:
  3. raise Exception('分母为零')
  4. else:
  5. print('a/b')

9.编写代码,调用CCircle方法,计算圆的面积。并且自己定义一个异常类,如果半径为负值,抛出自己定义的异常。

  1. import math
  2. def RadioError(Exception):
  3. def __init__(self,info):
  4. self.info=info
  5. def show(self)
  6. print(self.info)
  7. def CCircle(r):
  8. if r<0:
  9. raise RadiosError('半径为负值')
  10. else:
  11. print(math.pi*(r**2))

10.从命令行得到5个整数,放入一列表中,然后打印输出,要求:如果输入数据不为整数,要捕获产生的异常,显示“请输入整数”,捕获输入参数不足5个的异常(越界),显示“请输入至少5个整数”。

  1. list_1=[]
  2. for i in range(5):
  3. try:
  4. j=int(input('请输入一个整数:'))
  5. except:
  6. print('请输入整数!')
  7. else:
  8. list_1.append(j)
  9. if len(list_1) != 5:
  10. raise Exception ('请输入至少五个整数!')

4 迭代器和生成器

4.1 知识点思维导图

image.png

4.2 练习题

4.2.1 基础知识练习题

1.什么是迭代器?
就是每次重复都是基于上次结果而继续的。
2.为何要有迭代器?
列表元组等可以利用索引进行取值,但是字典和集合是无序的,没有办法根据索引进行取值,要想取字典的值就要用迭代器,就是取值的工具。
3.什么是可迭代的对象?
可能被for循环的,比如字符串,列表,字典,集合,元组。
4.什么是迭代器对象?
内置有iternext的方法的对象都是迭代器对象。
5.如何得到自定义的迭代器?
定义iternext方法
6.多个叠加装饰器的加载顺序与执行顺序是?
加载顺序是:从下往上
执行顺序是:从上往下
7.请用自己的话解释一下“迭代”的概念?
“迭代”是重复反馈过程的活动,其目的通常是为了接近并达到所需的目标或结果。每一次对过程的重复被称为一次“迭代”,而每一次迭代得到的结果会被用来作为下一次迭代的初始值。
8.迭代器是一个容器吗?
不是。因为我们耳熟能详的容器像列表、字典、元组都是可以存放数据的,而迭代器就是实现了next()方法的对象(用于遍历容器中的数据)。
9.迭代器可以回退(获取上一个值)吗?
迭代器的性质决定没有办法回退,只能往前进行迭代。但这并不是什么很大的缺点,因为我们几乎不需要在迭代中进行回退操作。
10.如何快速判断一个容器是否具有迭代功能?
判断该容器是否拥有 next() 和 iter() 魔法方法。
11. for 语句如何判断迭代器里边已经取空了?
迭代器通过 next() 方法每次返回一个元素,并指向下一个元素。如果当前位置已无元素,通过抛出 StopIteration 异常表示。

  1. 在 Python 原生支持的数据结构中,你知道哪一个是只能用迭代器访问的吗?

对于原生支持随机访问的数据结构(如tuple、list),可以使用迭代器或者下标索引的形式访问,但对于无法随机访问的数据结构 set 而言,迭代器是唯一的访问元素的方式。

4.2.2 程序设计练习题

1.使用生成器函数打印斐波那契数列前n项值。

  1. def Fibonaqi_Gen(number):
  2. n, a, b = 0, 0, 1
  3. while n < number:
  4. yield b
  5. a, b = b, a+b
  6. n += 1
  7. return "Done"
  8. #生成器打印需要用循环
  9. for i in Fibonaqi_Gen(6):
  10. print(i)
  11. #或者next()函数
  12. fibonaqi3 = Fibonaqi_Gen(3)
  13. print("next()")
  14. print(next(fibonaqi3))
  15. print(next(fibonaqi3))
  16. print(next(fibonaqi3))
  17. #使用try,except来获取return返回的信息
  18. fn = Feibonacci_Gen(6)
  19. while True:
  20. try:
  21. f = next(fn)
  22. print("fibonacci:", f)
  23. except StopIteration as e:
  24. print(f"StopIteration->{e.value}")
  25. break

2.写一个迭代器,要求输出2000年至今为止的所有闰年。

  1. import datetime as dt
  2. class LeapYear:
  3. def __init__(self):
  4. self.now = dt.date.today().year
  5. def isLeapYear(self,year):
  6. if (year % 4 == 0 and year % 100 != 0) or (year % 100 == 0 ):
  7. return True
  8. else:
  9. return False
  10. def __iter__(self):
  11. return self
  12. def __next__(self):
  13. while not self.isLeapYear(self.now):
  14. self.now -= 1
  15. temp = self.now
  16. self.now -= 1
  17. return temp

3.要求自己写一个 MyRev 类,功能与 reversed() 相同(内置函数 reversed(seq) )是返回一个迭代器,是序列 seq 的逆序显示)

  1. class MyRev:
  2. def __init__(self,data):
  3. self.data = data
  4. self.index = len(data)
  5. def __iter__(self):
  6. return self
  7. def __next__(self):
  8. if self.index == 0:
  9. raise StopIteration
  10. self.index -= 1
  11. return self.data[self.index]

5 闭包和装饰器

5.1 知识点思维导图

image.png
image.png

5.2 练习题

5.2.1 基础知识练习题

1.关于装饰器,下列说法错误的是( B)。
A. 装饰器是一个包裹函数
B. 装饰器只能有一个参数
C. 通过在函数定义的面前加上@符号和装饰器名,使得装饰器函数生效
D. 如果装饰器带有参数,则必须在装饰函数的外层再嵌套一层函数
4.判断题
闭包是内部函数对外部作用域的变量进行引用。()
当外部函数执行结束,其内部闭包引用的变量一定会立即释放。()
装饰器是一个变量。()
装饰器函数至少要接收一个函数。()
装饰器既能装饰带参数的函数,也能自己带参数。
5.内部函数引用了外部函数作用域的变量,那么内部函数叫作_
6.装饰器本质上是一个_
7.装饰器函数需要接收一个参数,这个参数表示_
8.在函数定义的前面添加装饰器名和_符号,实现对函数的包装。
9.支持参数的装饰器函数需要再多一层__函数。

5.2.2 程序设计练习题

1.写一个闭包函数 clo,接收整数参数 n ,返回一个函数 foo,foo 函数的功能是把 foo 参数和 n 相乘并把结果返回。

  1. def clo(n):
  2. def foo(*args):
  3. number = 5
  4. return number*n
  5. return foo
  6. print(clo(5)())

2.编写装饰器,在每次执行被装饰函数之前打印一句’每次执行被装饰函数之前都得先经过这里,这里根据需
求添加代码

  1. def wrapper(func): #装饰器函数
  2. def inner(*args, **kwargs): #装饰器内部函数
  3. print("每次执行被装饰函数之前都得先经过这里,这里根据需求添加代码")
  4. return func(*args, **kwargs) #调用被装饰函数
  5. return inner #返回装饰器函数内部函数名
  6. @wrapper # 这里等同于fn = wrapper(fn)
  7. def func(): #被装饰函数
  8. print("func is running...")
  9. func() #调用函数

3.编写装饰器,在每次执行被装饰函数之前让用户输入用户名,密码,给用户三次机会,登录成功之后,才能访
问该函数.

  1. def user_auth(func): #装饰器函数
  2. def inner(*args, **kwargs): #装饰器内部函数
  3. for i in range(3, 0, -1):
  4. while 1:
  5. print("33[31;0m请先登录33[0m".center(50, "*"))
  6. name = input("Username: ").strip()
  7. if name == "":
  8. print("33[31;0m用户名不能为空.33[0m")
  9. continue
  10. pwd = input("Password: ").strip()
  11. if pwd == "":
  12. print("33[31;0m密码不能为空.33[0m")
  13. continue
  14. if name == userinfo_dic["username"] and pwd == userinfo_dic["pwd"]: #认证通过
  15. print("33[32;0m登录成功.33[0m")
  16. return func(*args, **kwargs) #调用目标函数
  17. else: #认证失败
  18. if i == 1:
  19. exit("33[31;0m用户名或密码错误.程序自动退出.33[0m")
  20. else:
  21. print("33[31;0m用户名或密码错误.您还有%s次机会哦.33[0m" % (i-1))
  22. break
  23. return inner #返回装饰器函数内部函数名
  24. @user_auth # 这里等同于fn = wrapper(fn)
  25. def func(): #目标函数
  26. print("func is running...")
  27. userinfo_dic = {"username": "alex", "pwd":"123456"} #保存用户名和密码
  28. func()

6 数据库与GUI编程

6.1 知识点思维导图

image.png

20201023003450969.png

6.2 练习题

6.2.1 程序设计练习题

  1. 随机生成10个人名和对应的密码; 人名由三个汉字或者2个汉字组成,

姓 = [许, 张, 赵, 钱, 孙, 李, 朱, 杨]
名 = [彬, 群, 宁, 盼, 龙, 欢, 丹]
密码统一6位, 由字母和字符组成;
存储上述用户信息到数据库中,保存在数据库users中的userinfo表中;

  1. import random
  2. from random import choice as choice
  3. import string
  4. import pymysql
  5. # 生成指定位数密码, 前 n-1 位为数字, 最后一位为字符;
  6. def create_passwd(count=6):
  7. nums = random.sample(string.digits, count - 1)
  8. letters = random.sample(string.ascii_letters, 1)
  9. return "".join(nums + letters)
  10. # a = create_passwd()
  11. # print(a,type(a))
  12. # 生成随机的姓名, 有两个或三个汉字组成 ;
  13. def create_name():
  14. first = ['许', '张', '赵', '钱', '孙', '李', '朱', '杨']
  15. second = ['彬', '群', '宁', '盼', '龙', '欢', '丹']
  16. last = ['彬', '群', '宁', '盼', '龙', '欢', '丹', ' ' ]
  17. name = choice(first) + choice(second)+ choice(last)
  18. return name.rstrip()
  19. # print(create_name(),type(create_name()))
  20. def main():
  21. # 1.连接数据库 host user passwd charset
  22. conn = pymysql.connect(host='localhost',
  23. user='root',
  24. password='redhat',
  25. db='users',
  26. charset='utf8'
  27. )
  28. # 2.创建游标对象
  29. cur = conn.cursor()
  30. # 3.创建表
  31. create_table='create table userinfo (name varchar(30),password varchar(30));'
  32. cur.execute(create_table)
  33. # 4.加数据插入userinfo表中
  34. n = int(input("生成数据数:"))
  35. # 往数据库表中插入 n 条随机数据 ;
  36. for i in range(n):
  37. # cur.execute('insert into userinfo values("user1", "123");')
  38. sqli = "insert into userinfo values ('%s', '%s');" %(create_name(), create_passwd())
  39. cur.execute(sqli)
  40. # 提交数据,并关闭连接 ;
  41. conn.commit()
  42. cur.close()
  43. main()

2.编写一个程序,实现如下所示的用户登录验证GUI程序。
数据库服务器:192.168.179.231
数据库:test
用户名:test
密码:123456
数据表名:users
《面向对象程序设计》复习提纲(发布) - 图15

  1. import pymysql
  2. import wx
  3. #导入wxPython包
  4. class MainFrame(wx.Frame):
  5. #定义MainFrame类(代表程序的主窗体),它是wx.Frame类的子类
  6. def __init__(self):
  7. #主窗体的构造方法
  8. super().__init__(parent=None,id=-1,title="程序主窗体",size=(400,300))
  9. #调用wx.Frame类的构造方法来创建程序主窗体
  10. self.panel=wx.Panel(parent=self)
  11. #定义了panel对象,他是个wx.Panel类对象,代表一个面板
  12. self.title=wx.StaticText(parent=self.panel,label="请输入用户名和密码",pos=(140,20))
  13. #定义一个wx.StaticText控件类对象,这是一个文本标签类
  14. self.userLabel=wx.StaticText(self.panel,label="用户名:",pos=(50,50))
  15. self.userText=wx.TextCtrl(self.panel,pos=(100,50),size=(235,25),style=wx.TE_LEFT)
  16. #定义一个wx.TextCtrl控件对象,这是一个文本输入框,其中,pos代表位置,size代表大小,style代表是文本框的风格
  17. self.passLabel=wx.StaticText(self.panel,label="密 码:",pos=(50,90))
  18. self.passText=wx.TextCtrl(self.panel,pos=(100,90),size=(235,25),style=wx.TE_PASSWORD)
  19. self.btnOK=wx.Button(self.panel,label="确 定",pos=(105,130))
  20. #定义了按钮类wx.Button的对象
  21. self.btnCancel=wx.Button(self.panel,label="取 消",pos=(195,130))
  22. self.Bind(wx.EVT_BUTTON,self.OnClickOK,self.btnOK)
  23. #绑定btnOK的按钮点击事件的事件事件处理方法是OnClickOK
  24. self.Bind(wx.EVT_BUTTON,self.OnClickCancel,self.btnCancel)
  25. def validate(self,user,passwd):
  26. conn = pymysql.connect(
  27. host="192.168.179.231",
  28. user="test",password="123456",
  29. database="test",
  30. charset="utf8")
  31. cursors = conn.cursor()
  32. sqlStatement='select name,passwd from users where name="'+user+'" and passwd="'+passwd+'"'
  33. # print(sqlStatement)
  34. cursors.execute(sqlStatement)
  35. data = cursors.fetchone()
  36. # print(data)
  37. if data:
  38. return True
  39. else:
  40. return False
  41. def OnClickOK(self,event):
  42. #定义MainFrame类的方法OnClickOK,用来进行btnOk(“确定”)被点击之后事件处理
  43. #user="Tom"
  44. #passwd="123456"
  45. #这是要验证的用户名和密码
  46. userName=self.userText.GetValue()
  47. #从userText中取出输入的用户名,使用TextCtrl对象的GetValue()方法取出输入的内容
  48. userPass=self.passText.GetValue()
  49. #从passText中取出输入的密码
  50. message = ""
  51. if userName == "" or userPass == "":
  52. message = "用户名或密码不能为空"
  53. elif self.validate(userName,userPass) :
  54. message = "用户"+userName+"登录成功"
  55. else:
  56. message = "用户名或者密码不匹配"
  57. wx.MessageBox(message,"登录提示")
  58. #创建一个MessageBox对象,显示提示信息
  59. def OnClickCancel(self,event):
  60. #OnClickCancel定义Cancel按钮点击后的事件处理程序
  61. self.userText.SetValue("")
  62. #将userText文本框清空
  63. self.passText.SetValue("")
  64. if __name__ == "__main__" :
  65. app=wx.App()
  66. #定义一个wx.App类的对象app
  67. mainFrame=MainFrame()
  68. mainFrame.Show()
  69. app.MainLoop()
  70. #启动app的事件循环,等待捕获用户在GUI界面上的操作(即控件事件),然后进入事件响应程序,执行事件响应程序
  71. #执行完成以后,回到事件循环。直至捕获到退出事件发生,才结束应用程序。
  72. # import pymysql
  73. # conn = pymysql.connect(host="192.168.179.231",user="test",password="123456",database="test", charset="utf8")
  74. # cursors = conn.cursor()
  75. # user="mike"
  76. # passwd="123456"
  77. # sqlStatement='select name,passwd from users where name="'+user+'" and passwd="'+passwd+'"'
  78. # print(sqlStatement)
  79. # cursors.execute(sqlStatement)
  80. # data = cursors.fetchone()
  81. # print(data)