1.多态****
2.鸭子类型**
3.常用的内置方法
isinstance****
issubclass****
__str__****
__del__**
4.反射****
5.项目的生命周期*****
6.三层结构*****
多态是oop的三大特征之一
字面意思:多种形态,多种状态
一个事物具备多种形态
官方描述:不同对象可以响应(调用)同一个方法 产生不同的结果
多态不是什么新技术 我们在编写面向对象的程序时 其实就有多态存在
不同对象可以响应相同的方法 产生相同的结果
#对于对象的使用者而言 无需关心对象的具体实现 甚至不用关心具体的类型
极大的降低了使用难度
# import abc # class Animal(metaclass=abc.ABCMeta): # @abc.abstractmethod # def eat(self): # pass # @abc.abstractmethod # def bark(self): # pass # @abc.abstractmethod # def sleep(self): # pass # # class Person(Animal): # def eat(self): # print('筷子吃') # # def bark(self): # print('hello') # # def sleep(self): # print('躺着睡') # # class Cat(Animal): # def eat(self): # print('用爪子吃') # # def bark(self): # print('喵') # # def sleep(self): # print('蜷着睡') # # def animal_admin(animal): # animal.eat() # animal.bark() # animal.sleep() # # per1=Person() # cat1=Cat() # # animal_admin(per1) # animal_admin(cat1)
鸭子类型:
python不会强行限制 必须干什么 或不干什么
就比如封装中的私有属性 你也是可以强行访问的
同理 在多态中 子类中你可以不使用ABC模块
python 崇尚鸭子类型
class Cat: def eat(self): print("猫吃鱼") def sleep(self): print("猫睡觉") class Dog: def eat(self): print("狗吃肉") def sleep(self): print("狗睡觉") dog1 = Dog() cat1 = Cat() dog1.eat() cat1.eat() def animal_admin(animal): animal.eat() animal.sleep() animal_admin(dog1) animal_admin(cat1)
isinstance
判断一个对象是否是一个类的实例
a=100
print(type(a)==int)
isinstance()
print(isinstance('abc',object))
issubclass
issubclass(int,object)
class A:
pass
class B(A):
pass
print(issubclass(B,A)
参数1是子类 参数2是父类
__str__
__str__只在打印对象时自动触发
会在print对象时自动触发执行
# class Person: # def __init__(self,name,sex,age): # self.name = name # self.sex = sex # self.age = age # # def show_info(self): # print("my name is %s age %s sex %s" % # (self.name,self.age,self.sex)) # # 打印对象时自动触发 # def __str__(self): # print("run") # return ("my name is %s age %s sex %s" % # (self.name,self.age,self.sex)) # # p1 = Person("张大彪","man",20) # # p1.show_info() # # print(p1) # # print(Person)
__del__
对象从内存中删除时自动触发执行
1.程序运行完毕时
2.手动调用del
作用:用于做一些清理操作 比如开启了文件资源 就需要手动关闭
使用场景 当你的对象在创建时 同时开启了不属于解释器的资源
就需要在del中回收资源
也称之为析构函数 构造
# class MYRead: # def __init__(self,filepath,mode,encode): # self.filepath=filepath # self.mode=mode # self.encode=encode # self.file=open(filepath,mode,encoding=encode) # # def read_data(self): # return self.file.read() # def __del__(self): # self.file.close() # print('文件已经关闭') # # r=MYRead('今日内容','rt','utf-8') # print(r.read_data())
反射
一个对象具备可以修改自身属性及方法的能力
从代码级别来看 反射就是通过字符串来操作对象的属性(属性的增删改查)
hasattr 是否存在某个属性
getattr 获取某个属性
setattr 设置或修改属性
delattr 删除某个属性
# class Person: # def __init__(self,name): # self.name=name # # def say_hi(self): # print('hello name is %s'%self.name) # p1=Person('json') # print(hasattr(p1,'name')) # if hasattr(p1,'name'): # print(getattr(p1,'name',None)) # # # setattr(p1,'name','kgon') # print(getattr(p1,'name')) # # # setattr(p1,'age',200) # print(getattr(p1,'age')) # print(p1.__dict__) # # # delattr(p1,'age') # print(p1.__dict__) # if hasattr(p1,'say_hi'): # f=getattr(p1,'say_hi',None) # f()
# class Tools: # def download(self): # print('starting download') # def upload(selfself): # print('starting upload') # # t=Tools() # func=input('功能名称:') # if hasattr(t,func): # f=getattr(t,func,None) # f() # print(f) # else: # print('没有功能!')
通过反射来实现可插拔设计
# class MyDjango: # # 该框架 负责接收数据 再把数据交给框架的使用者 来处理 # def connect(self,server): # # 建立连接拿到一个数据 # data = "我是一个客户端 我需要一个网页文件" # # 处理数据 就不是框架要干的事情了 # if hasattr(server,"data_handler"): # f = getattr(server,"data_handler") # f(data) # # # # # class MyServer: # # # # def data_handler(self,data): # # print("收到一个数据:%s 正在处理" % data) # # # # server = MyServer() # # django = MyDjango() # # django.connect(server) # # # class YouServer: # # def data_handler(self,data): # print("Myserver 太low了 拔下来 插一个youServer 收到一个数据:%s 正在处理" % data) # # you = YouServer() # django.connect(you)
动态导入
import configparser #读取配置文件 获取模块的名称 c=configparser.ConfigParser() c.read('D:dailyday 27settings.conf') module_name=c.get('test','name') print(module_name) #通过反射动态导入需要的模块 import importlib importlib.import_module(module_name) #检测是否导入成功 import sys print(sys.modules) md = sys.modules[module_name] a = md.A() a.test()