typora-copy-images-to: upload
十一章
Bug的由来及分类
Bebug的常见类型
1、粗心导致的语法错误
2、知识不熟导致的错误
3、思路不清晰导致的问题
4、被动掉坑:程序代码逻辑没有错,只是因为用户错误操作或者一些“例外情况”而导致的程序崩溃
解决方案:使用print()函数或者使用“#”暂时注释部分代码。被动掉坑的解决方案:Python提供了异常处理机制,可以在异常出现的时候即时捕获,然后“内部消化”,让程序继续运行
不同异常类型的处理方式
1、多个except结构
捕获异常的顺序按照先子类后父类的顺序,为了避免遗漏可能出现的异常,可以在最后增加BaseException
try:
n1 = int(input("请输入第一个整数:"))
n2 = int(input("请输入第二个整数:"))
result = n1/n2
print("结果为:", result)
except ZeroDivisionError:
print("除数不能位0哦!!")
except ValueError:
print("不能将字符串转换位数字")
except BaseException as e:
print(e)
2、try…except…else结构
如果try中没有抛出异常,则执行else块,如果try中抛出异常,执行except块
try:
n1 = int(input("请输入第一个整数:"))
n2 = int(input("请输入第二个整数:"))
result = n1/n2
except BaseException as e:
print("出错了")
print(e)
else:
print("结果位:", result)
3、try…except…else…finally结构
finally块是无论是否发生异常都会被执行,通常使用来释放try块中申请的资源
Python中常见的异常类型
1、 ZeroDivvisionError 除(或去模)零(所有数据类型)
2、IndexError 序列中没有此索引(index)
3、KeyError 映射中没有这个键
4、NameError 未声明/初始化对象(没有属性)
5、SyntaxError Python语法错误
6、ValueError 传入无效的参数
traceback模块
使用traceback模块打印异常信息
import traceback
try:
print("----------------")
print(1/0)
except:
traceback.print_exc()
异常处理机制PyCharm的调式模式
1、断点
程序运行到此处,暂时挂起,停止执行。此时可以详细观察程序的运行情况,方便做出进一步的判断
2、进入调试视图
进入调试视图的三种方式:a,点击工具栏的按钮(绿色虫子)b,右键单击编辑区:点击debug模块名
3、快捷键:shift+F9
第十二章
两大编程思想
面向过程和面向对象
区别:面向过程应用在事物比较简单,可以用线性的思维去解决
面向对象应用在事物比较复杂,使用简单的线性思维无法解决
共同点:面向对象和面向过程都是解决实际问题的一种思维方式
连着相辅相成,并不是对立的,解决复杂问题,通过面向对象方式便于我们从宏观上把握事物之间的复杂关系,方便我们分析整个系统;具体到微观操作,任然使用面向过程方式来处理
类和对象的创建
类是多个类似事物组成的群体的统称。能够帮助我们快速理解和判断事物的性质
Python一切皆对象
类的创建
class Student :
pass
类的组成
类属性、实例方法、静态方法、类方法
class Student :
"""
直接写在类里的变量,称为类属性
"""
native_pace = "吉林"
# 初始化方法
"""self.name称为实体属性,进行了一个赋值的操作
将局部变量的name的值赋值给实体属性"""
def __init__(self, name, age):
self.name = name
self.age = age
# 实例方法
def eat(self):
print("学生吃饭。。。")
# 静态方法
@staticmethod
def Method():
print("我是静态方法,因为我使用了staticmethod进行修饰,所以我是静态方法")
# 类方法
@classmethod
def cm(cls):
print("我是类方法,因为我使用了classmethod进行修饰")
# 在类之外定义的称为函数,在类之内定义的称为方法
def drink():
print("喝水")
对象的创建
语法: 实例名 = 类名()
例子: stu = Student(“jack”,20)
有了实例,就可以调用对象中的方法
类对象与类属性、类方法与静态方法
类属性:类中方法外的变量称为类属性,被该类的所有对象所共享
类方法:使用@classmethod修饰的方法,使用类名直接访问的方法
静态方法:使用@staticmethod修饰的方法,使用类名直接访问的方法
动态绑定属性和方法
Python是动态语言,在创建对象之后,可以动态地绑定属性和方法
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
def eat(self):
print(self.name+"正在吃饭")
stu1 = Student("qq", 18)
stu2 = Student("pp", 20)
print("-----为stu2动态绑定一个性别gender---------")
stu2.gender = "女"
print(stu1.name, stu1.age)
print(stu2.name, stu2.age, stu2.gender)
def show():
print("show定义在类之外,是一个函数")
print("-----------为stu1动态绑定show------------")
stu1.show =show()
stu1.show
"""stu2.show(),无法调用show方法,因为stu2实例对象没有动态绑定show方法"""
第十三章
面向对象的三大特征
封装:提高程序的安全性,将数据(属性)和行为(方法)包装到类对象中,在方法内部堆属性进行操作,在类对象的外部调用方法。这样,无需关心方法内部的具体实现细节,从而隔离了复杂度
在Python中没有专门的修饰符用于属性的私有,如果该属性不希望在类对象外部被访问,前边使用两个”_“
class Student:
def __init__(self, name, age):
self.name = name
# 年龄不希望在类的外部被使用
self.__age = age
def show(self):
print(self.name, self.__age)
stu1 = Student("张三", 20)
stu1.show()
# 在类的外部可以通过 _Student__age 进行访问
print(stu1._Student__age)
继承: 提高代码的复用性
语法格式:class 子类名称(父类1,父类2…) :
pass
如果一个类没有继承任何类,则默认继承object,Python支持多继承,定义子类时,必须在其构造函数中调用父类的构造函数
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def info(self):
print("姓名:{0},年龄:{1}".format(self.name, self.age))
class Student(Person):
def __init__(self, name, age, stu_no):
super().__init__(name, age)
self.stu_no = stu_no
stu = Student("迪丽热巴", 18, 2018)
stu.info()
print(stu.stu_no)
class Teacher(Person):
def __init__(self, name, age, teachofyear):
super(Teacher, self).__init__(name, age)
self.teachofyear = teachofyear
tea = Teacher("古力娜扎", 20, 9)
tea.info()
多态: 提高程序的可扩展性和可维护性
方法重写
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def info(self):
print("姓名:{0},年龄:{1}".format(self.name, self.age))
class Student(Person):
def __init__(self, name, age, stu_no):
super().__init__(name, age)
self.stu_no = stu_no
def info(self):
print("姓名:{0},年龄:{1},学号:{2}".format(self.name, self.age, self.stu_no))
stu = Student("迪丽热巴", 18, 2018)
stu.info()
print(stu.stu_no)
class Teacher(Person):
def __init__(self, name, age, teachofyear):
super(Teacher, self).__init__(name, age)
self.teachofyear = teachofyear
def info(self):
print("姓名:{0},年龄:{1},教龄:{2}".format(self.name, self.age, self.teachofyear))
tea = Teacher("古力娜扎", 20, 9)
tea.info()
# 重写info方法也可以写成如下形式
"""
def info(self):
super().info() 继续调用原父类info方法
print(self.stu_no)
"""
object类
object类是所有类的父类,因此所有类都有object类的属性和方法,内置函数dir()可以查看指定对象所有属性,object有一个_str_()方法,用于返回一个对于“对象的描述”,对应于内置函数str()经常用于print()方法,帮我们查看对象的信息,所以我们经常会对_str_()进行重写
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return "我叫{0},今年{1}".format(self.name, self.age)
stu = Student("迪丽热巴", 18)
# 默认会调用__str__()这样的方法
print(dir(stu))
print(stu)
多态
简单的说,多态就是“具有多种形态”,它指的是:即便不知道一个变量所引用的对象到底是什么类型,任然可以通过这个变量调用方法,在运行过程中根据变量所引用对象的类型,动态决定调用那个对象中的方法。
静态语言与动态语言
静态语言与动态语言关于多态的区别
静态语言实现多态的三个必要条件
1、继承
2、方法重写
3、父类引用指向子类对象
动态语言的多态崇尚“鸭子类型”当看到一只鸟走起来像鸭子、游泳起来像鸭子、收起来也像鸭子,那么这只鸟就可以被称为鸭子。在鸭子类型中,不需要关心对象是什么类型,到底是不是鸭子,只关心对象的行为
特殊方法和特殊属性
特殊属性 _dict_ 获得类对象或实例对象所绑定的所有属性和方法的字典
特殊方法 _len_() 通过重写_len_()方法,让内置函数len()的参数可以是自定义类型
_add_() 通过重写_add_()方法,可使用自定义对象具有“+”功能
_new_() 用于创建对象
_init_() 对创建对象进行初始化
class A:
pass
class B:
pass
class C(A,B):
def __init__(self, name, age):
self.name = name
self.age = age
# c是C类型的一个实例对象
c = C("迪丽热巴", 18)
# 打印实例对象的属性字典
print(c.__dict__)
# 打印类对象的地址信息
print(C.__dict__)
print("----------------")
# __class__,输出了c对象的所属类
print(c.__class__)
# 打印C类的父类类型的元素
print(C.__bases__)
# 打印离C类最近的它的父类
print(C.__base__)
# 查看类的层次结构
print(C.__mro__)
# __subclasses__ 查看当前类的子类有那些
print(A.__subclasses__())
a = 10
b = 30
c = (a+b)
d = a.__add__(b)
print(d)
print(c)
class Student:
def __init__(self, name):
self.name = name
# 重写__add__()方法
def __add__(self, other):
return self.name + other.name
def __len__(self):
return self.name
stu1 = Student("迪丽热巴")
stu2 = Student("古力娜扎")
# 如果想让两个名字进行+操作,则可以重写__add__方法
# 实现了两个对象的加法运算(因为在Student类中,重写了__add__()特殊方法)
print(stu1+stu2)
print("------------------")
list = [11, 22, 33]
# len是内置函数len
print(len(list))
print(list.__len__())
print(stu1.__len__())
类的浅拷贝与深拷贝
1、变量的赋值操作
只是形成两个变量,实际上还是指向同一个对象
2、浅拷贝
Python拷贝一般都是浅拷贝,拷贝时,对象包含的子对象内容不拷贝,因此,源对象与拷贝对象会引用同一个子对象
3、深拷贝
使用copy模块的deepcopy函数,递归拷贝对象中包含的子对象,源对象和拷贝对象所有的子对象也不相同
class CPU:
pass
class Disk:
pass
class Computer:
def __init__(self, cpu, disk):
self.cpu = cpu
self.disk = disk
# (1)变量的赋值
cpu1 = CPU()
cpu2 = cpu1
print(cpu1, id(cpu1))
print(cpu2, id(cpu2))
# (2)类的浅拷贝
print("-------------")
# 创建一个硬盘类的对象
disk = Disk()
# 创建一个计算机类的对象
computer = Computer(cpu1, disk)
# 浅拷贝
import copy
computer2 = copy.copy(computer)
print(computer, computer.cpu, computer.disk)
print(computer2, computer2.cpu, computer2.disk)
print("---------------------")
# 深拷贝
computer3 = copy.deepcopy(computer)
print(computer, computer.cpu, computer.disk)
print(computer3, computer3.cpu, computer3.disk)