面向对象 三种特性之一 多态 鸭子类型 反射(反省) 多态是OOP的三大特征之一

字面意思:多种形态 多种状态

官方描述:不同的对象可以响应(调用)同一个方法 产生不同的结果(例如水的三相特征) 

多态不是什么新技术 我们编写面向对象的程序时 其实就有多态存在
import abc

class Animal(metaclass = abc.ABCMeat)

    @abc.abstractmetnod

  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(‘蜷着睡’)

obj = Person()
obj1 = Cat()
不同对象可以响应相同的方法 产生不同的结果
obj.eat()
obj1.eat()
对于对象的使用者而言 无需关心对象的具体实现 甚至不用关心具体类型  极大地降低了使用难度

def animal_admin(animal):
animal.eat()
animal.bark()
animal.sleep()

animal_admin(obj)
animal_admin(obj1)

class Pig(Animal):
def eat(self):
print("用鼻子拱")

def bark(self):
print("哼哼")

def sleep(self):
print("躺地上着睡")


obj2 = Pig()
animal_admin(obj2)


def MY_LEN(c):
print(c.__len__())


l1 = [1,2,3]

text = "abc"
MY_LEN(l1)
MY_LEN(text)

"""
鸭子类型
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 与 issubclacc 用法
"""
# 判断一个对象是否是一个类的实例
a = 100
# print(type(a) == int)
# print(isinstance(10,int))
# print(isinstance("abc",int))
# print(isinstance("abc",object))
class A:
pass

class B(A):
pass

# 参数1 是儿子 参数2 是老子
print(issubclass(B,A))

"""
反射
反省
一个对象具备可以修改自身属性及方法的能力
从代码级别来看 反射就是通过字符串来操作对象的属性(属性的增删改查)

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("jgon")


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) # 不存在age属性 就添加
print(getattr(p1,"age"))


delattr(p1,"name")


# 有一个工具类 提供了 upload 和download 功能
# 用户可以在控制台输入功能的名称来执行对应的功能
class Tools:

def download(self):
print("starting download")

def upload(self):
print("starting upload")

t = Tools()
func = input("输入要执行的功能名称:")
if hasattr(t,func):
f = getattr(t,func,None)
f()
print(f)
else:
print("没有这个功能")

# __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 Student:
# # 对象从内存中删除时自动触发执行
# def __del__(self):
# print("run del")
#
# stu = Student()
#
# del stu
#
# import time
# time.sleep(5)


# f = open("文件名称","rb")
# #
# #
# #
# #
# f.close()

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())