类的继承有两层意义:改变和扩展
多态就是两层意义的具体实现机制
面向对象的多态
不同数据类型执行相同的方法
不同子类调用父类相同的方法,这个方法可以体现多态的体现方式,多态体现在执行的时候
多态是由继承来的
面向对象的封装:
第一层面:类就是麻袋,调用者看不到类的属性
第二层面:类中定义私有的只在内部使用外部无法为访问
第三层面:明确区分内外,内部实现逻辑外部无法知晓,可以使用接口函数(访问函数)向外提供类的私有属性--这才是真正的封装
单下划线开头的变量:只能内部调用(只是一种约定)外部也可以调用
双下划线开头的变量:会重命名成 _类名__变量,调用的时候加上_类名__变量就行
反射/自省(适用于类和对象,类本身也是对象)一切皆对象
hasattr(a,'name')
getattr(a,'name')
setattr(a,'name','sss') #setattr(a,'func',lambda x:x+1)设置函数属性
delattr(a,'name')
动态导入模块:导入字符串模块(基于反射做的)
第一种方法:m=__import__(“modle.t”)
使用:m.t.test()
import importlib
m=importlib.import_module('modle.t')
使用:m.test()
双下划线下开头的attr方法(系统默认的函数属性,如果你定义了就使用你的,不定义就使用默认的)
__getaddtr__在调用一个不存在的对属性的时候会执行的方法,这个比较常用
__delattr__在删除对象的属性的时候会触发执行的方法, 直接操作字典的方式定义防止死循环
__serattr__在设置属性的时候会触发, 直接操作字典的方式定义
基于标准类进行包装
class List(list): def append(self, p_object): if type(p_object) is str: # self.append(p_object) super().append(p_object) else: print('只能添加字符串类型') def show_midlle(self): mid_index=int(len(self)/2) return self[mid_index]