多态:对象的多种状态 - 父类对象的多种(子类对象)状态
import abc class People(metaclass=abc.ABCMeta): def __init__(self, name): self.name = name @abc.abstractmethod def speak(self): pass class Chinese(People): def speak(self): print('说中国话') class England(People): def speak(self): print('说英国话') 多态的体现:功能或是需求,需要父类的对象,可以传入父类对象或任意子类对象 注:一般都是规定需要父类对象,传入子类对象 def ask_someone(obj): print('让%s上台演讲' % obj.name) # 父类提供,自己直接继承 obj.speak() # 父类提供,只不过子类重写了 ch = Chinese('王大锤') en = England('Tom') 传入Chinese | England均可以,因为都是People的一种状态(体现方式) ask_someone(ch) ask_someone(en) 传入str不可以,因为str的对象没有name和speak s = str('白骨精') ask_someone(s) p = People('kkk')
鸭子类型
需求:需要一个对象,该对象有name属性及speak方法,就可以作为一种状态的体现被传入 def ask_someone(obj): print('让%s上台演讲' % obj.name) obj.speak() 1.先规定:有什么属性及什么方法的类的类型叫鸭子类型 2.这些类实例化出的对象,都称之为鸭子,都可以作为需求对象的一种具体体现 class A: # 能有自己特有的属性和方法,可以和B完全不一样,但是必须有鸭子类型规定的属性和方法,不然就不是鸭子类型 def __init__(self, name): self.name = name def speak(self): print('说AAAA') class B: # 能有自己特有的属性和方法,可以和A完全不一样,但是必须有鸭子类型规定的属性和方法,不然就不是鸭子类型 def __init__(self, name): self.name = name def speak(self): print('说BBBB') ask_someone(B('B'))
格式化方法与析构方法
class A:
def __init__(self, name, age):
self.name = name
self.age = age
# 格式化方法:
在外界打印该类对象是被调用 # 格式化外界直接打印该类对象的字符串表示结果 def __str__(self): # return 'abc' # 外界打印A类的对象,都打印 字符串 abc # return super().__str__() # 系统默认的在父类中返回的是对象存放的地址信息 return '<name:%s | age:%s>' % (self.name, self.age) # 根据对象实际的属性格式化具体的输出内容
# 析构方法:
在对象被消耗的那一刹那被调用,在被消耗前可以做一些事情 def __del__(self): # del会在self代表的对象被消耗的时候被调用 # 我们可以在析构函数中释放该对象持有的其他资源, # 或者将一些持有资源持久化(保存到文件或数据库中) del self.name # 也可以将name存起来 a = A('老王', 88) print(a, type(a)) import time time.sleep(5) print('文件马上执行完毕,a就会被销毁')
了解
class B: # 了解:对象.语法的【】内部实现 def __setattr__(self, key, value): self.__dict__[key] = value # 系统默认实现,在名称空间添加名字 # self.__dict__[key] = value.lower() # 可以自定义处理一些内容 # 了了解:将对象添加属性的方式可以同字典形式 def __setitem__(self, key, value): self.__dict__[key] = value b = B() # 设置 b.name = 'BBB' # 内部走的是 __setattr__ b['age'] = 18 # 内部走的是 __setitem__ # 访问 print(b.name) print(b.age)
反射
通过 字符串 来操作类与对象的属性。 hasattr() 判断对象或者类的属性是否存在! getattr() 获取对象或者类的属性 参数1: 对象 参数2: '属性名' 参数3: 默认值 setattr() 设置对象或者类的属性 delattr() 删除对象或者类的属性 class BlackMedium: feature='Ugly' def __init__(self,name,addr): self.name=name self.addr=addr def sell_house(self): print('%s 黑中介卖房子啦,傻逼才买呢,但是谁能证明自己不傻逼' %self.name) def rent_house(self): print('%s 黑中介租房子啦,傻逼才租呢' %self.name) b1 = BlackMedium('阿萨斯','安达顺') 用hasattr()来判断属性是否存在 类不能判断对象的属性 print(hasattr(BlackMedium,'name')) # False 对象能判断类的属性 print(hasattr(b1,'feature')) #True print(hasattr(b1,'name')) #True print(hasattr(BlackMedium,'feature')) #True 用getattr()来获取属性的值 类不能获取对象的属性的值 print(getattr(BlackMedium,'name','asd')) #asd 对象能获取类的属性的值 print(getattr(b1,'feature','asd')) #Ugly print(getattr(BlackMedium,'feature','asd')) #Ugly print(getattr(b1,'name','asd')) #阿萨斯 用setattr()来设置属性 没有回创建 setattr(b1, 'age', 18) print(b1.age) # 18 有会改值 setattr(b1,'name','qwe') print(b1.name) #qwe 用delattr()删除对象或者类的属性 print(b1.name) # 阿萨斯 delattr(b1, 'name') print(b1.age) #18 print(b1.name) # 报错!