L19-python核心编程-面向对象编程(day1、2)

目录

一、面向对象编程的基本介绍

1、解决菜鸟买电脑的故事

二、类和对象

1、类

2、对象

 3、类和对象的关系

4、类的定义

5、对象的定义

三、魔法方法

1、类的初始方法——__init__()方法

2、类的字符信息输出——__str__()方法

 3、类的析构方法——__del__()方法

 四、继承

 1、单继承

2、多继承

2.1、子类重写父类同名属性方法

2.2、子类调用父类同名属性方法 

3、多层继承

五、私有属性与私有方法

一、公有属性和公有方法

二、私有属性和私有方法

六、多态

 七、属性与方法

一、类属性

二、实例属性

三、类方法

四、静态方法

八、异常

一、捕获多个异常——try...except...

二、捕获异常信息描述并存储

三、异常的传递

1、抛出自定义异常—— raise语句

 2、异常处理中抛出异常

d9作业

d10作业:


一、面向对象编程的基本介绍

1、解决菜鸟买电脑的故事

方式一
1)在网上查找资料
2)根据自己预算和需求定电脑的型号 MacBook 15 顶配 1W8
3)去市场找到苹果店各种店无法甄别真假 随便找了一家
4)找到业务员,业务员推荐了另外一款 配置更高价格便宜,也是苹果系统的 1W
5)砍价30分钟 付款9999
6)成交
方式二
1)找一个靠谱的电脑高手
2)给钱交易


买电脑的第一种方式:
强调的是步骤、过程、每一步都是自己亲自去实现的
这种解决问题的思路我们就叫做面向过程
买电脑的第二种方式:
强调的是电脑高手, 电脑高手是处理这件事的主角,对我们而言,我们并不必亲自实现整个步骤只需要调用电脑高手就可以解决问题
这种解决问题的思路就 是面向对象

二、类和对象

1、类

具有相似内部状态和运动规律的实体的集合(或统称为抽象)。
具有相同属性和行为事物的统称

2、对象

1、某一个具体事物的存在 ,在现实世界中可以是看得见摸得着的。
2、可以是直接使用的

 3、类和对象的关系

1、类就是创建对象的模板
2、对象就是根据类产生的一个具体实例

对象类与对象关系
类是同一类对象的属性和行为的抽象和总结
类描述同一类对象应包含的数据
类描述同一类对象的行为特征
类是抽象的,是一个概念模型
一个类可以找到多个对象
类是对象的模板,对象是该类的实例
 
万事万物皆对象
面向对象方法的核心
具有明确的属性和行为
程序是对象的集合,通过消息交互
 
类就是创建对象的模板
对象就是根据类产生的一个具体实例

4、类的定义

类(Class) 由3个部分构成:
    类的名称:类名
    类的属性:一组数据
    类的方法:允许对进行操作的方法 (行为)
定义一个类,语法格式:
    class 类名:
        方法列表
# 新式类定义形式
class Hero(object): 
    def info(self): 
        print("英雄各有见,何必问出处。")


self  代表类的实例,而非类
类的方法与普通的函数只有一个特别的区别——它们必须有一个额外的第一个参数名称, 按照惯例它的名称是 self。
所谓的self,可以理解为自己可以把self当做C++中类里面的this指针一样理解,就是对象自身的意思
某个对象调用其方法时,python解释器会把这个对象作为第一个参数传递给self,所以开发者只需要传递后面的参数即可
 

5、对象的定义

python中,可以根据已经定义的类去创建出一个或多个对象。
    对象名1 = 类名() 
    对象名2 = 类名() 
    对象名3 = 类名()
创建对象demo:

添加和获取对象属性:

class Hero(object):
    def info(self):
        '''
        当对象调用方法的时候,python会把第一个参数传递到我们的self之中
        :return:
        '''
        print(self)
        print('沧浪涤尘,流水清心')
#实例化对象
yasuo = Hero()

#调用info 方法
yasuo.info()

#print(yasuo)
#print(id(yasuo))

#给对象添加属性
yasuo.name = '亚索'
yasuo.hp = '2500'
yasuo.atk = '500'
yasuo. armor = '200'

print('英雄%s 的生命值是 %s' %(yasuo.name,yasuo.hp))
print('英雄%s 的攻击力是 %s' %(yasuo.name,yasuo.atk))
print('英雄%s 的护甲值是 %s' %(yasuo.name,yasuo.armor))

'''

<__main__.Hero object at 0x003EC0B8>
沧浪涤尘,流水清心
#<__main__.Hero object at 0x003EC0B8>
#4112568
英雄亚索 的生命值是 2500
英雄亚索 的攻击力是 500
英雄亚索 的护甲值是 200

进程已结束,退出代码 0

 在方法内通过self获取对象属性

 

class Hero(object):
    def move(self):
        print('正在路上')
    def attack(self):
        print('哈撒给,索利亚卡痛!')
    def info(self):
        print('英雄%s 的生命值是 %s' % (self.name, self.hp))
        print('英雄%s 的攻击力是 %s' % (self.name, self.atk))
        print('英雄%s 的护甲值是 %s' % (self.name, self.armor))
yasuo = Hero()

yasuo.name = '亚索'
yasuo.hp = '2500'
yasuo.atk = '500'
yasuo. armor = '200'

yasuo.info()
yasuo.move()
yasuo.attack()

'''

英雄亚索 的生命值是 2500
英雄亚索 的攻击力是 500
英雄亚索 的护甲值是 200
正在路上
哈撒给,索利亚卡痛!

进程已结束,退出代码 0

三、魔法方法

1、类的初始方法——__init__()方法

python中提供__init__()方法,
在创建对象的时候,直接设置对象的属性
语法格式:
    def __init__(self):
        pass
例子:在上面的Car类上,添加__init__()
__init__()方法,创建对象时,默认被调用。
__init__(self) 默认有1个参数名字为self,如果在创建对象时传递了多个个参数
语法格式:
    def __init__(self,参数1,...,参数n):
        self.属性1 = 参数1
        ......
        self.属性n = 参数n
 
class Car(object):
    # 初始化方法
    def __init__(self):
        self.wheel = 4
        self.color = '蓝'
    def getCarInfo(self):
        print('车子的轮子是%s个,颜色是%s' %(self.wheel,self.color))

BNW = Car()
BNW.getCarInfo()
BNW1 = Car()
BNW1.getCarInfo()


'''

车子的轮子是4个,颜色是蓝
车子的轮子是4个,颜色是蓝

进程已结束,退出代码 0
class Car(object):
    # 初始化方法
    def __init__(self,wheel,color):
        self.wheel = wheel
        self.color = color
    def getCarInfo(self):
        print('车子的轮子是%s个,颜色是%s' %(self.wheel,self.color))

BNW = Car(4,'bai')
BNW.getCarInfo()
BNW1 = Car(8,'hei')
BNW1.getCarInfo()


''''

车子的轮子是4个,颜色是bai
车子的轮子是8个,颜色是hei

进程已结束,退出代码 0

2、类的字符信息输出——__str__()方法

当使用print输出对象的时候,只要自己定义了__str__(self)方法,那么就会打印从在这个方法中return的数据,举例如下:
class Car:
        def __init__(self, newWheelNum, newColor):
        self.wheelNum = newWheelNum
        self.color = newColor
        def __str__(self):
        msg = "嘿...我的颜色是" + self.color + ",我有%d"%self.wheelNum+ "个轮胎..."
        return msg

#创建对象:    
BMW = Car(4, "白色")
print(BMW)
执行:python3  XXX.py  
嘿...我的颜色是白色,我有4个轮胎...
注意:__str__()返回字符串类型

class Car(object):
    # 初始化方法
    def __init__(self,wheel,color):
        self.wheel = wheel
        self.color = color
    def getCarInfo(self):
        print('车子的轮子是%s个,颜色是%s' %(self.wheel,self.color))
    def __str__(self):
        msg = '这是一辆%s的车,有%s 个轮子'%(self.color,self.wheel)
        return msg
bwm = Car(6,'lan')
print(bwm)


'''

这是一辆lan的车,有6 个轮子

进程已结束,退出代码 0

 3、类的析构方法——__del__()方法

创建对象后,python解释器默认调用__init__()方法;
当删除一个对象时,python解释器也会默认调用一个方法,这个方法为__del__()方法。
语法格式:
    def __del__(self):
        pass 

class animal(object):
    def __init__(self,name):
        print('__init__方法被调用')
        self.name = name

    def __del__(self):
        print('__del__方法被默认调用')
        print('%s 已经被删除' % self.name)

dog = animal('二哈涛狗')


'''

__init__方法被调用
__del__方法被默认调用
二哈涛狗 已经被删除

进程已结束,退出代码 0

 注意 :
当有1个变量保存了对象的引用时,此对象的引用计数就会加1
当使用del删除变量指向的对象时,如果对象的引用计数不会1,比如3,那么此时只会让这个引用计数减1,即变为2,当再次调用del时,变为1,如果再调用1次del,此时会真的把对象进行删除

 四、继承

 1、单继承

故事情节:煎饼果子老师傅在煎饼果子界摸爬滚打几十年,拥有一身精湛的煎饼果子技术,并总结了一套"古法煎饼果子配方"。
可是老师傅年迈已久,在嗝屁之前希望把自己的配方传承下去,于是老师傅把配方传给他的徒弟大猫...

class master(object):
    def __init__(self):

        #属性
        self.kongfu = '古法配方'

    def make_cake(self):
        print('按照%s 制作煎饼' % self.kongfu)
#定义prentice类,继承自master  master是父类,prentice子类
class prentice(master):
    pass

cat = prentice()#子例的实例化对象

print(cat.kongfu)
cat.make_cake()

'''

配方
按照古法配方 制作煎饼

进程已结束,退出代码 0

2、多继承

故事继续:大猫掌握了师傅的配方,可以制作古法煎饼果子。但是大猫是个爱学习的好孩子,他希望学到更多的煎饼果子的做法,于是通过百度搜索,找到了一家煎饼果子培训学校。(多继承)

 

class master(object):
    def __init__(self):
        #属性
        self.kongfu = '古法配方'
    def make_cake(self):
        print('按照%s 制作煎饼' % self.kongfu)
    def dayandai(self):
        print('师傅的大烟袋')

class school(object):
    def __init__(self):
        # 属性
        self.kongfu = '现代配方'
    def make_cake(self):
        print('按照%s 制作煎饼' %self.kongfu)
    def xiaoyandai(self):
        print('学校的小烟袋')

#定义prentice类,继承自master,school  master和school是父类,prentice子类
class prentice(master,school):#继承多个父类
    pass

cat = prentice()#子例的实例化对象

#print(cat.kongfu)
print(prentice().kongfu)
cat.make_cake()

#子类的魔法属性__mro__决定了属性和方法的查找顺序
print(prentice.__mro__)

#两个都继承了,不重名不受影响
cat.dayandai()
cat.xiaoyandai()


'''

古法配方
按照古法配方 制作煎饼
(<class '__main__.prentice'>, <class '__main__.master'>, <class '__main__.school'>, <class 'object'>)
师傅的大烟袋
学校的小烟袋

进程已结束,退出代码 0

2.1、子类重写父类同名属性方法

故事继续:大猫掌握了 师傅的配方 和 学校的配方,通过研究,大猫在两个配方的基础上,创建了一种全新的煎饼果子配方,称之为 "猫氏煎饼果子配方"。(子类重写父类同名属性和方法)

class master(object):
    def __init__(self):

        #属性
        self.kongfu = '古法配方'

    def make_cake(self):
        print('按照%s 制作煎饼' % self.kongfu)

class school(object):
    def __init__(self):
        # 属性
        self.kongfu = '现代配方'
    def make_cake(self):
        print('按照%s 制作煎饼' %self.kongfu)

'''
 "猫氏煎饼果子配方"(子类重写父类同名属性和方法) 
'''
class prentice(master,school):#继承多个父类
    def __init__(self):
        self.kongfu = '猫氏配方'
    def make_cake(self):
        print('按照%s制作一份煎饼' %self.kongfu)

cat = prentice()
print(cat.kongfu)
cat.make_cake()
print(prentice.__mro__)

'''

猫氏配方
按照猫氏配方制作一份煎饼
(<class '__main__.prentice'>, <class '__main__.master'>, <class '__main__.school'>, <class 'object'>)

进程已结束,退出代码 0

2.2、子类调用父类同名属性方法 

故事继续:大猫的新配方大受欢迎,但是有些顾客希望也能吃到古法配方和 现代配方 的煎饼果子...(子类调用父类的同名属性和方法)

class master(object):
    def __init__(self):

        #属性
        self.kongfu = '古法配方'

    def make_cake(self):
        print('按照%s 制作煎饼' % self.kongfu)

class school(object):
    def __init__(self):
        # 属性
        self.kongfu = '现代配方'
    def make_cake(self):
        print('按照%s 制作煎饼' %self.kongfu)

'''
 "猫氏煎饼果子配方"(子类重写父类同名属性和方法) 
'''
class prentice(master,school):#继承多个父类
    def __init__(self):
        self.kongfu = '猫氏配方'
    def make_cake(self):
        print('按照%s制作一份煎饼' %self.kongfu)

    '''故事继续:大猫的新配方大受欢迎,但是有些顾客希望也能吃到
    古法配方和 现代配方 的煎饼果子...(子类调用父类的同名属性和方法)'''

    def make_old_cake(self):
        # 调用格式 :父类类名.父类方法(self)
        print('执行master 类的__init__ 之前 的self.kongfu是什么 %s'% self.kongfu)
        master.__init__(self)#初始化,如果不初始化配方一直是猫氏配方
        print('执行master 类的__init__ 之后 的self.kongfu是什么 %s' % self.kongfu)
        master.make_cake(self)

    def make_new_cake(self):
        print('执行master 类的__init__ 之前 的self.kongfu是什么 %s' % self.kongfu)
        school.__init__(self)#初始化,不初始化就还是古法配方
        print('执行master 类的__init__ 之前 的self.kongfu是什么 %s' % self.kongfu)
        school.make_cake(self)
cat = prentice()
cat.make_cake()
print('-'*30)
cat.make_old_cake()
print('-'*30)
cat.make_new_cake()
print('-'*30)
cat.make_cake()#现在已经变成了现代配方


'''

按照猫氏配方制作一份煎饼
------------------------------
执行master 类的__init__ 之前 的self.kongfu是什么 猫氏配方
执行master 类的__init__ 之后 的self.kongfu是什么 古法配方
按照古法配方 制作煎饼
------------------------------
执行master 类的__init__ 之前 的self.kongfu是什么 古法配方
执行master 类的__init__ 之前 的self.kongfu是什么 现代配方
按照现代配方 制作煎饼
------------------------------
按照现代配方制作一份煎饼

进程已结束,退出代码 0

3、多层继承

故事继续:大猫的煎饼果子店非常红火,终于有一天,他成了世界首富!!
但是他也老了,所以他希望把 师傅的配方 和 学校的配方 以及自己的配方 继续传承下去...(多层继承)

代码同上(删除后八行)
#大猫要去世了,小猫来继承大猫的遗产
class prenticeprentice(prentice):
    pass
xiaocat = prenticeprentice()
xiaocat.make_cake()
xiaocat.make_new_cake()
xiaocat.make_old_cake()

'''

按照猫氏配方制作一份煎饼
执行master 类的__init__ 之前 的self.kongfu是什么 猫氏配方
执行master 类的__init__ 之前 的self.kongfu是什么 现代配方
按照现代配方 制作煎饼
执行master 类的__init__ 之前 的self.kongfu是什么 现代配方
执行master 类的__init__ 之后 的self.kongfu是什么 古法配方
按照古法配方 制作煎饼

进程已结束,退出代码 0

五、私有属性与私有方法

一、公有属性和公有方法

类的属性
命名格式:由字母开头,总体由字母、数字和_构成
使用方法:在类外面 :对象名.属性名  在类内部 : self.属性名
类的方法 
使用 def 关键字可以为类定义一个方法,与一般函数定义不同,类方法必须包含参数 self,且为第一个参数    
    命名格式:由字母开头,总体由字母、数字和_构成
    使用方法:在类外面 :对象名.方法名(实参表)  在类内部 : self.方法名(实参表)

例子:class Car:
        def setCarInfo(self, num, color):
            self.wheelNum = num
            self.color = color
        def getCarInfo(self):
            print("车子轮子数目是%d,车子颜色是%s"%(self.wheelNum,self.color))    
        def toot(self):        
            print("车子在鸣笛,嘟嘟....")    

二、私有属性和私有方法

Python中以属性命名方式来区分,如果在属性名前面加了2个下划线'__',则表明该属性是私有属性,否则为公有属性(方法也是一样,方法名前面加了2个下划线的话表示该方法是私有的,否则为公有的)。

类的私有属性
        命名格式:__private_attrs  由__开头,总体由字母、数字和_构成
        使用方法: 只在类内部 : self.__private_attrs
类的方法 
        命名格式:__private_function  由__开头,总体由字母、数字和_构成
        使用方法:只在类内部 : self.__private_function(实参表)

例子:

class People:
    def setName(self, name):
            self.__name = name    #访问私有属性 __name    
    def __getName(self):             # 定义私有方法
    return self.__name
    def printName(self):
    print('姓名是%s'%self.__getName())       # 调用私有方法 __getName()
 

'''
以__开头的属性是私有属性
def __是私有方法
'''

class people(object):
    def __init__(self,name):
        self.__name = name

    def getName(self):
        return self.__name

people = people('小明')
#print(people.__name)#会报错,无法打印,说明只能在类的内部使用
print(people.getName())#getName是公有属性,可以调用

'''

小明

进程已结束,退出代码 0

六、多态

定义时的类型和运行时的类型不一样,此时就成为多态.
 多态的概念是应用于Java和C#这一类强类型语言中,而Python崇尚“鸭子类型 ”.

鸭子类型:
    虽然我想要一只"鸭子",但是你给了我一只鸟。 但是只要这只鸟走路像鸭子,叫起来像鸭子,游泳也像鸭子,我就认为这是鸭子.

class F1(object):
    def show(self):
        print('F1.show')

class S1(F1):
    def show(self):
        print('S1.show')

class S2(F1):
    def show(self):
        print('S2.show')

def func(obj):
    #python是弱类型,即无论传递过来的是什么,obj变量都能够指向它,这也就没有所谓的多态
    print(obj.show())

s1 = S1()
func(s1)

s2 = S2()
func(s2)

'''

S1.show
None
S2.show
None

进程已结束,退出代码 0

另一个例子: 

from math import pi


class Shape:
    def __init__(self, name):
        self.name = name

    def area(self):
        pass

    def fact(self):
        return "我是一个二维的形状。"

    def __str__(self):
        return self.name


class Square(Shape):
    def __init__(self, length):
        super().__init__("Square")
        self.length = length

    def area(self):
        return self.length**2

    def fact(self):
        return "正方形的每个角都是90度。"


class Circle(Shape):
    def __init__(self, radius):
        super().__init__("Circle")
        self.radius = radius

    def area(self):
        return pi*self.radius**2


a = Square(4)
b = Circle(7)
print(b)
print(b.fact())
print(a.fact())
print(b.area())


'''


Circle
我是一个二维的形状。
正方形的每个角都是90度。
153.93804002589985

进程已结束,退出代码 0

在这里,我们可以看到在父类中使用了诸如__str __()之类的未在子类中重写的方法。

由于多态性,Python解释器自动识别出对象a(Square类)的fact()方法被重写。它使用了在子类中定义的那个。

另一方面,由于对象b的fact()方法没有被重写,因此可以从Parent Shape类中使用它。

 七、属性与方法

一、类属性

定义
    类属性就是类对象所拥有的属性,它被所有类对象的实例对象所共有,在内存中只存在一个副本,这个和C++中类的静态成员变量有点类似。对于公有的类属性,在类外可以通过类对象和实例对象访问

二、实例属性

定义:一个类的实例对象所拥有的属性
特点:独立的,一对一
拥有者:每个对象都拥有自己的实例属性
语法格式:
class 类名:
    def  方法名(self):
        self.属性名  #实例属性
    .....
#创建类的对象后
对象名.属性名 = 值    # 第一次执行,添加新属性

三、类方法

类方法:     是类对象所拥有的方法
特点:    @classmethod  在上面修饰 ,方法第一个参数必须是类对象
     @classmethod
    def 类方法名(cls):
        执行代码
访问格式:
    类名.类方法名()
    实例对象名.类方法名()
应用:    访问类属性,并且可以对类属性进行修改

四、静态方法

静态方法: 是类对象所拥有的方法
特点:    @staticmethod来进行修饰,不需要多定义参数
语法格式:
    @staticmethod
    def 静态方法名():
        执行代码
访问格式:
    类名.静态方法名()
应用:    访问类属性,并且可以对类属性进行修改

 实际上,Python 完全支持定义类方法,甚至支持定义静态方法。Python 的类方法和静态方法很相似,它们都推荐使用类来调用(其实也可使用对象来调用)。

类方法和静态方法的区别在于,Python会自动绑定类方法的第一个参数,类方法的第一个参数(通常建议参数名为 cls)会自动绑定到类本身;但对于静态方法则不会自动绑定。

使用 @classmethod 修饰的方法就是类方法;使用 @staticmethod 修饰的方法就是静态方法。

class Bird:
    # classmethod修饰的方法是类方法
    @classmethod
    def fly (cls):
        print('类方法fly: ', cls)
    # staticmethod修饰的方法是静态方法
    @staticmethod
    def info (p):
        print('静态方法info: ', p)
# 调用类方法,Bird类会自动绑定到第一个参数
Bird.fly()  #①
# 调用静态方法,不会自动绑定,因此程序必须手动绑定第一个参数
Bird.info('crazyit')
# 创建Bird对象
b = Bird()
# 使用对象调用fly()类方法,其实依然还是使用类调用,
# 因此第一个参数依然被自动绑定到Bird类
b.fly()  #②
# 使用对象调用info()静态方法,其实依然还是使用类调用,
# 因此程序必须为第一个参数执行绑定
b.info('fkit')


'''

类方法fly:  <class '__main__.Bird'>
静态方法info:  crazyit
类方法fly:  <class '__main__.Bird'>
静态方法info:  fkit

进程已结束,退出代码 0

 从上面粗体字代码可以看出,使用 @classmethod 修饰的方法是类方法,该类方法定义了一个 cls 参数,该参数会被自动绑定到 Bird 类本身,不管程序是使用类还是对象调用该方法,Python 始终都会将类方法的第一个参数绑定到类本身,如 ① 号、② 号代码的执行效果。

上面程序还使用 @staticmethod 定义了一个静态方法,程序同样既可使用类调用静态方法,也可使用对象调用静态方法,不管用哪种方式调用,Python 都不会为静态方法执行自动绑定。

在使用 Python 编程时,一般不需要使用类方法或静态方法,程序完全可以使用函数来代替类方法或静态方法。但是在特殊的场景(比如使用工厂模式)下,类方法或静态方法也是不错的选择。

八、异常

当Python检测到一个错误时,解释器就无法继续执行了,反而出现了一些错误的提示,这就是所谓的"异常"。


例如:f = open("Good.txt")    #打开一个不存在的文件
Traceback (most recent call last):
  File "error.py", line 3, in <module>
    f = open("Good.txt")
FileNotFoundError: [Errno 2] No such file or directory: 'Good.txt'

一、捕获多个异常——try...except...

例子1:
#!/usr/bin/python 
try:
    f = open("Good.txt")
    print(num)
except (IOError,NameError):
    pass
执行结果: 不会出现错误提示
 
例子2:
#!/usr/bin/python 
try:
    f = open("Good.txt")
    print(num)
except (IOError, NameError):
    print('find error')
执行结果: find error

二、捕获异常信息描述并存储

获取一个异常的信息描述,并存储
语法格式:
    try :
        可能会出现异常的语句
    except  异常类型 as 存储位置变量名:
        pass   #表示直接略过     #或者执行的语句
捕获多条异常,并存储
语法格式:    
    try :
        可能会出现异常的语句
    except  (异常类型1[, 异常类型2,....,异常类型N]) as 存储位置变量名:
        pass   #表示直接略过     #或者执行的语句

'''
try:
except
'''

try:
    file = open('good.txt')
    print(num)
except(IOError,NameError) as rest :#有错误就走这个代码
    print('---find error---')
    print(rest)
print("-----")
print(rest)


'''

---find error---
[Errno 2] No such file or directory: 'good.txt'
-----
Traceback (most recent call last):
  File "C:/Users/linxi/Desktop/嵌入式笔记/level19/python/2d10.py", line 134, in <module>
    print(rest)
NameError: name 'rest' is not defined

进程已结束,退出代码 1

 获取所有异常的信息描述
语法格式:
    try :
        可能会出现异常的语句
    except :
        pass   #表示直接略过     #或者执行的语句
捕获所有异常,并存储
语法格式:    
    try :
        可能会出现异常的语句
    except  Exception as 存储位置变量名:
        pass   #表示直接略过     #或者执行的语句

'''
try:
except
'''

try:
    print(num)
    file = open('good.txt')

except Exception as a :#有错误就走这个代码
    print('---find error---')
    print(a)


'''

---find error---
name 'num' is not defined

进程已结束,退出代码 0

三、异常的传递

异常传递一般会出现在try嵌套使用时和多函数之间调用,这两种情况下:

如果try嵌套,那么如果里面的try没有捕获到这个异常,那么外面的try会接收到这个异常,然后进行处理,如果外边的try依然没有捕获到,那么再进行传递。。。

1、抛出自定义异常—— raise语句

raise语句 : 可以引发一个异常。异常/错误对象必须有一个名字。自定义一个异常类,且它们应是Error或Exception类的子类。
语法格式:
class 自定义异常类名(Error或者Exception):
    #异常类的方法....
    def __init__(self, ......):
        ......
抛出异常语句格式:
    raise 异常类名(传参列表)
例子:如图

 2、异常处理中抛出异常

在使用try...except...中,如果出现异常,可以选择捕捉该异常,自己处理;也可以选择抛出该异常,让系统处理(默认处理)。
语法格式:添加一个判断条件,若条件为真,表示捕捉异常自己处理;若为假,可以抛出异常,系统默认处理
    try:
        可能产生异常的语句
    except  Exception as 存放位置:
        if 条件:
            处理该异常
        else:
            #重新抛出异常
            raise        

 

class shortInput(Exception):
    def __init__(self,length):
        self.length = length

def main():
    try:
        s = input('请输入')
        if len(s) < 3:
            raise shortInput(len(s))
    except shortInput as e:
        print(e)
main()


'''
请输入5
1

进程已结束,退出代码 0

d9作业

1.完成随堂代码
2.代码完成:
a)小明爱跑步,爱吃东西。
1)小明体重75.0公斤
2)每次跑步会减肥0.5公斤
3)每次吃东西体重会增加1公斤
4)小美的体重是45.0公斤

class xiaoming(object):
    def __init__(self,name,tizhong,aihao1,aihao2):
        self.aihao2 = aihao2
        self.aihao1 = aihao1
        self.tizhong = tizhong
        self.name = name
    def __str__(self):
        return ('%s的体重是%.2f爱好是%s和%s'%(self.name,self.tizhong,self.aihao1,self.aihao2))
    def paobu(self):
        print('小明因为%s一次,瘦了0.5公斤' %self.aihao1)
        self.tizhong -= 0.5

    def chidongxi(self):
        print('小明因为%s一次,胖了1公斤' %self.aihao2)
        self.tizhong += 1

class xiaomei(object):
    def __init__(self,name,tizhong):
        self.tizhong = tizhong
        self.name = name
    def __str__(self):
        info = '%s的体重是%s'%(self.name,self.tizhong)
        return info

xiaoming = xiaoming('小明',75,'跑步','吃东西')
xiaoming.paobu()
xiaoming.chidongxi()
print(xiaoming)
print(xiaomei('小美',45))


'''

小明因为跑步一次,瘦了0.5公斤
小明因为吃东西一次,胖了1公斤
小明的体重是75.50爱好是跑步和吃东西
小美的体重是45

进程已结束,退出代码 0

d10作业:

1.完成随堂代码
2.创建员工类Employee,属性有姓名name、能力值ability、年龄age(能力值为100-年龄),功能有doWork(),该方法执行一次,该员工的能力值-5,创建str方法,打印该员工的信息
3.创建老板类Boss,属性有金钱money,员工列表employeeList(存储员工类对象),工作量work,功能有雇佣员工addEmployee(),雇佣后将员工添加至列表中,雇佣一人money减5000,金额不足时不能雇佣新员工;开始工作startWork(),工作开始后,依次取出员工列表中的员工开始工作,员工能力值减少的同时总的工作量work也减少,当工作量work为0时,工作结束,调用endWork(该方法为Boss类方法,打印员工的能力值信息)方法,如果所有员工使用完后,依然没有完成工作,则提示老板需要雇佣新员工,并打印剩余工作量
4.创建Boss类对象,默认执行雇佣3个员工,年龄分别为30,40,50,然后死循环开始工作,直至工作完成。

class Employee:
    def __init__(self,name,age):
        self.age = age
        self.name = name
        self.ability = 100-age
    def dowork(self):
        self.ability -= 5
    def str(self):
        print('name: %s ,age: %s ,ability: %s '%(self.name,self.age,self.ability))
yuangong = Employee('小王',25)
yuangong.str()

class Boss:
    def __init__(self,money,work,employeelist):
        self.money = money
        self.work = work
        self.list = employeelist
    #雇佣员工
    def addEmployee(self,name,age):
        if self.money >= 5000:
            e = Employee(name,age)
            self.list.append(e)
            self.money -= 5000
        else:
            print('没钱,招不来')
    #要工作了,工作一次能量-5
    def startWork(self):
        for person in self.list:
            while person.ability > 0:
                person.dowork()
                self.work -= 5
            if self.work == 0:
                self.endwork()
                break
            if self.work > 0:
                print('工作还有%s,招人'%self.work)
    #工作结束了,还剩多少能量
    def endwork(self):
        for i in self.list:
            i.str()

yuangong1 = Employee('1',30)
yuangong1.str()
yuangong2 = Employee('2',40)
yuangong2.str()
yuangong3 = Employee('3',50)
yuangong3.str()
boss = Boss(20000,1000,[yuangong1,yuangong2,yuangong3])
boss.startWork()



'''


name: 小王 ,age: 25 ,ability: 75 
name: 1 ,age: 30 ,ability: 70 
name: 2 ,age: 40 ,ability: 60 
name: 3 ,age: 50 ,ability: 50 
工作还有930,招人
工作还有870,招人
工作还有820,招人

进程已结束,退出代码 0

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值