美文网首页
Python-面向对象2

Python-面向对象2

作者: 徐弱西 | 来源:发表于2019-07-30 21:52 被阅读0次

    今日内容

    面向对象的三大特性

    • 封装

    • 继承与派生

    • 多态与多态性

    绑定方法与非绑定方法

    内置的方法

    元类

    异常处理

    内容回顾

    1.面向对象编程与面向过程编程

    面向过程:

    核心是过程二字,过程指的是解决问题的步骤,即先干什么再干什么…基于该思想编写程序就好比在设计一条流水线

    优点:复杂的问题流程化,进而简单化

    缺点:可扩展性差

    面向对象:

    核心是对象二字,对象指的是特征与技能的结合体,基于该思想编写程序就好比在创造一个世界,程序员就是这个世界的上帝,在上帝眼里一切事物均是对象

    优点:可扩展性性高

    缺点:编程的复杂度相对于面向过程要高

    2.定义类

    类就是一系列属性和方法的结合体

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n26" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">class OldboyStudent:
    school='oldboy'

    def init(self,name,age,sex):
    self.name=name
    self.age=age
    self.sex=sex

    def choose_course(self,course):
    pass

    类你也可以把它理解成是一个容器,你往里面存了很多名字,

    存不是我们首要的目的,取才是!

    如果你要访问类里面的名字

    print(OldBoy.dict)

    print(OldBoy.dict['school'])

    print(OldBoy.school) python给你提供了访问属性的简便操作 统一采用句点符

    只要是句点符操作的左边一定是一个容器(名称空间) 比如: 模块,类,对象</pre>

    3.实例化对象

    调用init完成实例化 self.name = name,这种语法不是在获取属性而是在往对象里面新增属性

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n29" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">obj = OldBoy('jason')
    print(obj.dict) # 查看对象独有的属性
    print(obj.school) # 还可以查看类里面共有的属性</pre>

    • 产生一个空对象

    • 调用init实例化(将空对象和传入的参数一并传给init)

    • 将实例化好的对象返回出来

    4.属性查找

    先从对象自己的名称空间找,如果没有则去类名称空间中找,如果还没有则去父类中找...

    补充:

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n41" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"># python中一切皆对象
    l = list([1,2,3])
    obj1 = OldBoy('egon')
    print(type(l))
    print(type(obj1))

    你定义一个类 可不可以认为就是定义了一个新的数据结构

    你定义一个列表之后,是不是配套的有一堆相应的操作该列表的方法?append pop ...

    那对象刚好也有对应的绑定方法</pre>

    5.绑定给对象的方法

    在类中定义的函数,叫方法,类可以调用但是需要手动传入self

    该方法在没有被任何装饰器修饰的前提下,其实就是给对象用的而且是绑定给对象的绑定方法

    绑定特点:谁来调就会将谁当作第一个参数自动传入

    6.封装

    1、什么是封装 “装”的意思就往一个容器中放入一系列属性 “封”的意思就是藏起来,在内部可以看到,但对外部是隐藏的

    2、为什么要用封装

    将复杂的操作封装成简单的接口,并严格控制接口的调用过程

    3、如何用封装 但凡是双下划线开头(不能是双下划线结尾)的属性,会被隐藏起来,类内部可以直接使用 而类外部无法直接使用,即封装是对外不对内的

    这种隐藏的特点: 1、只是一种语法上的变形,会将开头的属性变形为:自己的类名_属性名(_n=1 #Foo__n=1) 2、该变形只在类定义阶段发生一次,在类定义阶段之后新增的开头的属性并不会发生变形 3、隐藏是对外不对内的 4、在继承中,父类如果不想让子类覆盖自己的同名方法,可以将方法定义为私有的

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n52" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">class Teacher:
    def init(self,name,age):

    self.__name=name

    self.__age=age

    self.set_info(name,age)

    def tell_info(self):
    print('姓名:%s,年龄:%s' %(self.__name,self.__age))

    def set_info(self,name,age):
    if not isinstance(name,str):
    raise TypeError('姓名必须是字符串类型')
    if not isinstance(age,int):
    raise TypeError('年龄必须是整型')
    self.__name=name
    self.__age=age

    t=Teacher('egon',18)
    t.tell_info()

    t.set_info('egon',19)
    t.tell_info()</pre>

    1.继承与派生

    1.什么是继承

    继承就是一种新建类的方式,新建的类称为子类或者派生类,被继承的类称之为父类或者基类或者超类

    子类会继承所有父类的属性和方法,即可以直接使用这些属性和方法

    2.为什么要用继承

    减少代码冗余

    3.如何使用

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n63" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">class Parent1:
    pass
    class Parent2:
    pass
    class Son1(parent1):
    pass

    python支持多继承,一个类可以有多个父类,但在java中只能有一个

    class Son2(parent1,parent2):
    pass
    print(Son1.bases) # 查看当前类的所有的基类
    print(Son2.bases)

    那你是否会好奇想看看我们定义的Parent类它有没有偷偷摸摸的继承谁呢?

    print(Parent1.bases)
    print(Parent2.bases)

    切换python解释器3.x >>> 2.x得出一个结论

    """
    在python3中,如果没有显示地继承任何类,那默认继承object类
    在python2中,如果没有显示地继承任何类,也不会继承object类


    在python中类分为两种:
    新式类:
    但凡继承object的类,或者该类的子类都是新式类

    :在python3中所有的类都是新式类
    经典类
    没有继承object类,以及该类的子类都是经典类
    也就意味着经典类和新式类这对儿概念只在python2中有
    python3中只有新式类
    """</pre>

    4.基于继承减少代码冗余的案例+派生/衍生

    对象与对象之间总结相似的特征与技能得到类 类与类之间总结相似的属性和特征得到父类

    http://www.cnblogs.com/linhaifeng/articles/7340153.html

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n67" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"># 代码实例
    import pickle

    class OldboyStudent:
    school = 'oldboy'

    def init(self,name,age,sex):
    self.name = name
    self.age = age
    self.sex = sex

    def choice_course(self):
    print('%s is choosing course'%self.name)

    def save(self):
    with open(self.name,'wb') as f:
    pickle.dump(self,f)

    class OldboyTeacher:
    school = 'oldboy'

    def init(self,name,age,sex,level):
    self.name = name
    self.age = age
    self.sex = sex
    self.level = level

    def score(self):
    print('%s is score'%self.name)

    def save(self):
    with open(self.name,'wb') as f:
    pickle.dump(self,f)
    stu = OldboyStudent('alex',30,'male')
    stu.save()

    tea = OldboyTeacher('egon',18,'male',10)
    tea.save()

    回过头来看,上面的代码是否存在相似的部分。我们刚好学过解决类之间解决代码冗余的方式

    class OldboyPeople:
    school = 'oldboy'

    def save(self):
    with open(self.name, 'wb') as f:
    pickle.dump(self, f)

    初步继承类抽取,思考继承之后对象查找属性和方法的顺序

    stu.save()
    stu.school

    刚刚只是讲属性和方法抽成了父类,但是init里面也有重复的代码,应该也可以抽取

    class OldboyPeople:
    school = 'oldboy'
    def init(self,name,age,sex):
    self.name = name
    self.age = age
    self.sex = sex

    def save(self):
    with open(self.name, 'wb') as f:
    pickle.dump(self, f)

    先不考虑老师和学生init中不同的,先全部继承这个父类统一的init,发现也可以使用到父类的init

    派生概念

    在子类能够使用父类所有的属性和方法的同时,自身还有一些额外的属性和方法

    小思考:如果派生的属性和方法恰巧和父类的一样,那在查找属性和方法的时候先找到谁呢? >>> 还是按查找顺序来

    再回过头来看老师的init中有额外的level参数,不应该在父类中添加默认参数,只能自己重写init方法,但是又有重复的代码出现

    def init(self,name,age,sex,level):
    OldboyPeople.init(self,name,age,sex)
    self.level = level
    """
    在子类派生出的新方法中重用父类的方法
    方式1:指名道姓访问,与继承没有任何关系
    OldboyPeople.init(self,name,age,sex)
    言外之意还有一种跟继承有关系的能够重用父类的方法的方式,先不着急说
    """</pre>

    5.继承原理

    刚刚我们一直在讨论的是单继承下属性查找的顺序,那如果是多继承情况呢?

    单继承测试

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n71" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">class Foo:
    def f1(self):
    print('Foo.f1')

    def f2(self): #self=obj
    print('Foo.f2')
    self.f1() #obj.f1()

    class Bar(Foo):
    def f1(self):
    print('Bar.f1')


    obj=Bar()
    obj.f2()</pre>

    多继承

    <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" cid="n73" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"># F(A,B,C) 无论是新式类还是经典类,都是从左往右挨个走到底 画图 切换python版本演示,记得加文件头coding:utf-8

    2、多继承的属性查找“:对象自己-》对象的类-》从左往右一个一个的分支找下去

    class D:

    def test(self):

    print('D')

    pass
    class E:
    def test(self):
    print('E')

    class F:
    def test(self):
    print('F')

    class A(D):

    def test(self):

    print('A')

    pass

    class B(E):
    def test(self):
    print('B')

    class C(F):
    def test(self):
    print('C')

    class G(A,B,C):

    def test(self):

    print('G')

    pass

    obj=G()
    obj.test()</pre>

    如果是菱型继承的话就不一样了(不考虑object)>>>广度优先!

    <pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="python" cid="n75" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">#3、新式类:广度优先
    class A(object):
    def test(self):
    print('from A')
    class B(A):
    # def test(self):
    # print('from B')
    pass
    class C(A):
    # def test(self):
    # print('from C')
    pass
    class D(B):
    # def test(self):
    # print('from D')
    pass
    class E(C):
    # def test(self):
    # print('from E')
    pass
    class F(D,E):
    # def test(self):
    # print('from F')
    pass

    obj=F()
    print(F.mro()) # 查找属性的顺序遵循mro列表(只有新式类中才有mro方法)
    obj.test()
    </pre>

    回过头再来看通过继承关系调用父类的方法

    <pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="python" cid="n77" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"># 方式二:super(自己的类名,self).父类中的方法名()

    调用super会得到一个特殊的对象,该对象是专门用来引用父类中的方法的,

    具体的:该对象会严格按照当前类的MRO列表从当前类的父类中依次查找属性,即这种方式是严格依赖于继承的

    ps:在python3中可以简写为super()

    class OldboyPeople:
    def init(self,name,age,sex):
    self.name=name
    self.age=age
    self.sex=sex

    class OldboyTeacher(OldboyPeople):
    def init(self,name,age,sex,level):
    # OldboyPeople.init(self,name,age,sex)
    super(OldboyTeacher,self).init(name,age,sex)
    self.level=level

    tea1=OldboyTeacher('egon',18,'male',10)
    print(tea1.name,tea1.level)

    class A:
    def f1(self):
    print('A')
    super().f2() # super()会基于当前所在的查找位置继续往后查找
    def f2(self):
    print('A')
    class B:
    def f2(self):
    print('B')
    class C(A,B):
    def f2(self):
    print('C')

    obj=C()
    print(C.mro())
    obj.f1()
    </pre>

    实际工作中要谨慎使用多继承,编程是解耦合,而继承则是强耦合

    6.多态与多态性

    1.什么是多态

    同一种事物的多种形态(动物:人,猫,狗)

    2.为何要用多态

    多态性:指的是可以在不用考虑对象具体类型的前提下,直接调用对象的方法

    3.如何使用多态

    <pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="python" cid="n87" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">class Animal:
    def talk(self):
    pass

    class People(Animal):
    def talk(self):
    print('say hello')

    class Dog(Animal):
    def talk(self):
    print('汪汪汪')

    class Pig(Animal):
    def talk(self):
    print('哼哼哼')

    peo1=People()
    dog1=Dog()
    pig1=Pig()

    不用考虑对象具体类型的前提下,直接调用对象的方法

    peo1.talk()
    dog1.talk()
    pig1.talk()
    """
    再来想车是不是有很多牌子,你去学车需要说专门学哪个牌子的车的驾驶方式吗?
    """

    来你之前也一直在用多态性:不用考虑对象具体类型的前提下,直接调用对象的方法

    l=list([1,2,3])
    s=str('hello')
    t=tuple((4,5,6))

    l.len()
    s.len()
    t.len() # 我不需要考虑这三个具体是什么类型,只要是容器类型就都能调用len这个方法

    再来看多态性能够实现的条件是什么?父类有的方法名子类也必须叫这个方法才行

    class Animal:
    def talk(self):
    pass

    class People(Animal):
    def jiao(self):
    print('say hello')

    class Dog(Animal):
    def han(self):
    print('汪汪汪')

    class Pig(Animal):
    def hou(self):
    print('哼哼哼')

    多态性能实现的条件就是父类给子类定义了一个标准,动物都必须会叫,并且叫的方法都必须是talk

    但是你现在能约束我说子类必须叫这个方法吗?

    那有没有一种情况能够做到说子类必须按照父类定义的标准

    import abc
    class Animal(metaclass=abc.ABCMeta): # 父类存在的意义就是用来定义规范
    @abc.abstractmethod
    def talk(self):
    pass

    Animal() # 抽象基类不能被实例化!!!

    class People(Animal):
    def jiao(self):
    print('say hello')
    class Dog(Animal):
    def han(self):
    print('汪汪汪')
    class Pig(Animal):
    def hou(self):
    print('哼哼哼')

    上面三个类 一实例化都会报错

    但是python推崇的是自由,简约并不希望限制程序员的开发

    鸭子类型:只要你长得像鸭子,说话像鸭子,那你就是鸭子!

    class People:
    def talk(self):
    print('say hello')
    class Dog:
    def talk(self):
    print('汪汪汪')
    class Pig:
    def talk(self):
    print('哼哼哼')

    再来看linux中:一切皆文件!

    class Disk:
    def read(self):
    print('disk read')
    def write(self):
    print('disk write')
    class Process:
    def read(self):
    print('process read')
    def write(self):
    print('processes write')
    class Memory:
    def read(self):
    print('memory read')
    def write(self):
    print('memory write')
    </pre>

    7.类中的装饰器

    <pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="python" cid="n89" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"># property

    人体的BMI指数

    """
    成人的BMI数值:
    过轻:低于18.5
    正常:18.5-23.9
    过重:24-27
    肥胖:28-32
    非常肥胖, 高于32
      体质指数(BMI)=体重(kg)/ 身高^2(m)
      EX:70kg÷(1.75×1.75)=22.86
    """
    class People:
    def init(self,name,height,weight):
    self.name=name
    self.height=height
    self.weight=weight

    @property
    def bmi(self):
        return self.weight / (self.height ** 2)
    

    egon=People('egon',1.80,75)
    egon.height=1.82

    print(egon.bmi())

    print(egon.bmi)

    了解

    class People:
    def init(self,name):
    self.__name=name

    @property
    def name(self):
        return self.__name
    
    @name.setter
    def name(self,val):
        # print('=====>准备修改名字的值:',val)
        if type(val) is not str:
            raise TypeError('名字的值必须为str类型')
        self.__name=val
    
    @name.deleter
    def name(self):
        # del self.__name
        print('不让删啊老铁')
    

    classmethod

    staticmethod

    </pre>

    8.反射

    通过字符串来获取类或对象的属性或方法

    <pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="python" cid="n92" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">#1、反射:指的是通过字符串来操作类或者对象的属性
    class People:
    country='China'
    def init(self,name):
    self.name=name

    obj=People('egon')

    涉及四个内置函数

    hasattr

    print('country' in People.dict)
    print(hasattr(People,'country'))

    getattr

    print(People.dict['country'])
    print(getattr(People,'country'))
    print(getattr(People,'country1111',None))

    setattr

    People.dict['x']=111
    print(People.x)
    setattr(People,'x',111)
    print(People.dict)

    delattr

    delattr(People,'country')
    print(People.dict)

    应用

    class Ftp:
    def get(self):
    print('get...')

    def put(self):
        print('put...')
    
    def auth(self):
        print('auth...')
    
    def run(self):
        while True:
            cmd=input('>>: ').strip() #cmd='get'
            if hasattr(self,cmd):
                method=getattr(self,cmd)
                method()
            else:
                print('输入的方法不存在')
    

    obj=Ftp()
    obj.run()
    </pre>

    9.内置方法

    <pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="python" cid="n94" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"># str

    getattr 注意是对象获取自己没有的属性时才会触发(属性和方法)

    setattr

    </pre>

    10.元类

    https://www.cnblogs.com/Dominic-Ji/p/10520256.html

    异常处理

    1.什么是异常?

    异常是错误发生的信号,程序一旦出错,如果程序中还没有相应的处理机制,那么该错误就会产生一个异常抛出来,程序的运行也随之终止

    <pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="python" cid="n100" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">print('start')
    x = 1
    y = 2
    if
    print('end') # 程序一句也不会运行直接报错,运行前会先检测语法
    </pre>

    异常分为三部分: 异常的类型(一个个的类) 异常的内容、提示信息 异常的追踪/定位信息信息

    异常的分类:

    • 语法上的错误(如上例)

    • 逻辑上的错误

      <pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="python" cid="n108" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit;"># NameError
      age = 12
      a

      IndexError

      l = [1,2,3]
      l[123]

      KeyError

      d = {'name':'jason'}
      d['password']
      </pre>

    2 为何要进行异常处理

    增强程序的健壮性

    3 如何进行异常处理

    <pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="python" cid="n112" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">try
    ...
    except
    ...
    </pre>

    <pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="python" cid="n113" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">#针对逻辑上的异常才应该使用try...except去捕捉异常进行处理

    1、异常的单分支(单个except)

    2、异常的多分支(多个except)

    3、万能异常:Exception,可以匹配所有种类的异常(挨个注释挨个尝试)

    try:
    age
    l=[1,2,3]
    l[100]
    d={'x':1}
    d['y']
    import os
    os.xxx
    except Exception as e: # as语法将错误信息赋值给变量e
    print('万能异常')
    print(e)
    print('其他代码')

    4、多分支+Exception,注意Exception一定要放到except 其他异常的的后面

    5、try...else,else会在被检测的代码块没有异常发生的情况下执行, else一定要与except连用,并且一定要放到多个except后面

    6、try...finally,finally的代码,无论被检测的代码有无异常,都会执行,通常在finally内做一些回收资源的事情

    try:
    f = open('a.txt','w',encoding='utf-8')
    f.read()
    finally:
    f.close()
    print('other...')

    7、主动触发异常raise 异常类型(’异常的内容‘)

    应用于程序中自定义某种法则,一旦不遵循则会像抛出语法异常一样,终止程序的运行

    class People:
    def init(self,name):
    if not isinstance(name,str):
    raise TypeError('%s must be str type'%name)
    self.name = name

    8、断言

    l = [1,2,3]
    assert len(l) > 0

    9 自定义异常

    class MyError(BaseException):
    def init(self,msg):
    super().init()
    self.msg=msg
    def str(self):
    return '<%s>' %self.msg

    raise MyError('我自己定义的异常') # 主动抛出异常其实就是将异常类的对象打印出来,会走str方法
    </pre>

    相关文章

      网友评论

          本文标题:Python-面向对象2

          本文链接:https://www.haomeiwen.com/subject/dcgorctx.html