面向编程理解-5

38 环境管理器:

Ø  类内有__enter__ 和 __exit__方法的类,被称为环境管理器

Ø  能够用with语句进行管理的对象必须是环境管理器

Ø  __enter__将在进入with语句时被调用并返回由as变量管理的对象

Ø  __exit__将在离开with时被调用,且可以用参数来判断在离开with语句时是否有异常发生,并做出相应的处理

38.1 示例

class Cooker:

    def open_gas(self):

        print("打开天然气")

    def close_gas(self):

        print("关闭天然气")

扫描二维码关注公众号,回复: 160075 查看本文章

    def dowork(self):

        print("制作烧饼")

    def __enter__(self):

异常类型

 
        self.open_gas()

异常类型的值

 
        return self

 

    def __exit__(self, exc_type, exc_value, exc_tb):

不清楚

 
        self.close_gas()

        if exc_type is None:   

            print("正常离开")

        else:

            print("异常退出")

 
 

对象

 
  

with Cooker() as c:

    c.dowork()

39  编码规范

PEP8编码规范

创建多个对象,而且都有自己的名字空间,这样不会产生冲突

继承,封装,多态

40  继承(inheritance)和派生(derived)

40.1继承的目的

继承的目的延续旧的功能

派生的目的在旧的功能之上添加新的功能

40.2 作用

用继承派生机制,可以将一些共有功能加载基类上,实现代码共享,在不改变超类的代码的基础上改变原有功能

基类(base class) /超类(super class) /父类(father class)

派生类(derivedclass)/子类(child class)

40.3 单继承语法:

class 类名(超类名):

   ·······

40.4 继承说明:

   任何类都直接或间接的继承自object类

object类是一切类的超类

40.5 __base__属性

作用:

用来记录此类的基类(类实例)

import human

class Student(human.Human):

    pass

s1 = Student()

print(s1.__class__.__base__())  #<human.Human object at 0x7f15d106a7b8>

print(s1.__class__.__base__)   # <class 'human.Human'>

print(s1.__class__.__base__.__base__) # <class 'object'>

print(Student.__base__)     # <class 'human.Human'>

print(Student.__base__.__base__) # <class 'object'>

print(object.__base__)  # None

40.6 覆盖 override(重写 overwrite)

什么是覆盖

覆盖是指有继承关系的类中,子类中实现了与基类同名的方法,在子类实例调用该方法时,实际调用的是子类中覆盖的版本,这种现象叫做覆盖

子类对象显示调用基类方法的方式

基类名.方法名(对象,参数) #先调用子类,如果没有再找基类

实例.方法名(参数) #此时实例调用的是子类自己的方法(如果子类中有该方法名)

40.7 super函数

Ø  super(type,obj) 返回绑定超类的实例(要求obj必须为type类型的实例)

Ø  super()返回绑定的超类的实例,等同于(class,实例方法的第一个参数),此方法必须用在方法内部 

40.7.1 作用:

返回绑定超类的实例,用超类的实例来调用其自身的方法

40.7.2 示例

class A:

    def hello(slef):

        print('A类中的hello(self)')

class B(A):

    def hello(self):

        print("B类种的hello")

 

base = B()

base.hello()  # B类种的hello

super(B, base).hello()  # A类中的hello(self) 等同于 B.__base__.hello(base)

                                      #类名.方法名(实例,参数)

class A:

    def hello(slef):

        print('A类中的hello(self)')

class B(A):

    def hello(self):

        print("B类种的hello")

    def super_hello(self):

        self.hello()

        super(B,self).hello()

        super().hello()

base = B()

base.hello()  # B类种的hello

super(B, base).hello()  # A类中的hello(self) 等同于 B.__base__.hello(base)

base.super_hello()

B类种的hello

A类中的hello(self)

B类种的hello

A类中的hello(self)

A类中的hello(self)

41用与类的函数

issubclass(cls,类或类元组)

判断一个类是否是继承自其它的类,如果此类cls是类(class)或元组中的一个派生类则返回True,否则返回False

class A:

    pass

class B(A):

    pass

class C(B):

    pass

class D(C):

    pass

print(issubclass(C,A))  #True

print(issubclass(D,B))  # True

print(issubclass(D,A))  #True

print(issubclass(bool,int)) #True

print(issubclass(bool,float)) #False

42 显示调用基类的构造方法:

   def__init__(self,·········):

     ············

示例

class Human(object):

    """docstring for ClassName"""

    def __init__(self, name, age):

        self.name = name

        self.age = age

    def infos(self):

        print('name:', self.name, 'age:', self.age)

class Student(Human):

注意:没有self,还有先后顺序

 
    def __init__(self, name, age, score):

        super(Student, self).__init__(name, age)

        # self.name = name

        # self.age = age

        self.score = score

    def infos(self):

        print("name", self.name, 'age', self.age, 'score:', self.score)

h1 = Human("张珊", 18)

h1.infos()

s1 = Student('小玲', 20, 99)

s1.infos()

name: 张珊 age: 18

name 小玲 age 20 score: 99

43 多态 polymorphic

43.1 定义

字面意思是‘多种状态’

多态是在有继承/派生关系的类中,调用基类对象的方法,实际能调用子类的覆盖方法的现象

多态调用的方法与对象相关,不与类型相关

class Shape:

    def draw(self):

        self.drawSelf()

class Point(Shape):

    def drawSelf(self):

        print("❀个鸟")

class Circle(Point):

    def drawSelf(self):

        print("画个圆")

shape = Point()

shape.draw()   #❀个鸟

shape = Circle()

shape.draw()   #画个圆

44 面向对象思想的特征:

1 封装

2 继承(派生)

3 多态 (由于此特征,可以使列表存放多种数据类型)

45 封装:enclosure

45.1 作用

封装是指隐藏类的实现细节,让使用者不关心这些细节

注:python的封装是假的(模拟)封装

45.2 私有实例变量和方法:

Python类中,以双下划线'__'开头,不以双下划线结尾的表示符为私有成员

私有成员分为:

   私有属性和私有方法

私有成员在子类和类外部无法访问

class A:

    def __init__(self, args):

        self.__p = args

    def showA(self):

        print("self.__p:", self.__p)

 

a = A(100)

a.showA()      

print(a.__p)

执行结果

self.__p: 100

Traceback (most recent call last):

  File "enclosure.py", line 12, in <module>

    print(a.__p)

AttributeError: 'A' object has no attribute '__p'

class A:

    def __init__(self, args):

        self.__p = args

    def showA(self):

       return self.__p

 

a = A(100)

print(a.showA())  #100  可以拿到值

46 多继承 multiple inheritance

  多继承是指一个子类继承两个或两个以上的基类

46.1 多继承的语法:

class 类名(超类名1,超类名2···········):

   ···········

class Car:

    def run(self, speed):

        print("汽车以", speed, 'km/h速度行驶')

class Plane:

    def fly(self, height):

        print("在海拔", height, '米上空飞行')

class PlaneCar(Car, Plane):

    '''PlaneCar类同时继承飞机和汽车

        没有pass,什么也没写

    '''

pl = PlaneCar()

pl.fly(20000)   #在海拔 20000 米上空飞行

pl.run(600)    #汽车以 600 km/h速度行驶

46.2 多继承的缺陷

标识符冲突的问题

要谨慎使用多继承

class A:

    def __init__(self):

        self.name = 'A'

class B(object):

    """docstring for B"""

    def __init__(self):

        self.name = 'B'

class AB(A, B): #换成(B,A) 结果是B

    def infos(self):

        print(self.name)

ab = AB()

ab.infos()   #A


猜你喜欢

转载自blog.csdn.net/areigninhell/article/details/79918363
今日推荐