38 环境管理器:
Ø 类内有__enter__ 和 __exit__方法的类,被称为环境管理器
Ø 能够用with语句进行管理的对象必须是环境管理器
Ø __enter__将在进入with语句时被调用并返回由as变量管理的对象
Ø __exit__将在离开with时被调用,且可以用参数来判断在离开with语句时是否有异常发生,并做出相应的处理
38.1 示例
class Cooker: def open_gas(self): print("打开天然气") def close_gas(self): print("关闭天然气") def dowork(self): print("制作烧饼") def __enter__(self):
def __exit__(self, exc_type, exc_value, exc_tb):
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):
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 |