Python11-13


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)

猜你喜欢

转载自blog.csdn.net/qq_48424500/article/details/115209772