多态、多态性

多态

多态通俗理解起来,就像迪迦奥特曼有三种形态一样,怎么变还是迪迦奥特曼

  • 定义:多态指的是一类事物有多种形态

示例如下:

'''动物有多种表现形态,人也是动物之一,在这里会说话就是动物'''
class Animal():
def speak(self):
print('动物发出的叫声--->', end='') class Cat(Animal):
def speak(self):
print('喵喵喵') class Dog(Animal):
def speak(self):
print('汪汪汪') class People(Animal):
def speak(self):
print('啊啊啊') ani = Animal() ani.speak()
cat = Cat()
cat.speak() ani.speak()
dog = Dog()
dog.speak() ani.speak()
peo = People()
peo.speak() # 结果
动物发出的叫声--->喵喵喵
动物发出的叫声--->汪汪汪
动物发出的叫声--->啊啊啊

多态性

  • 多态性是指可以不用考虑对象具体类型的情况下直接使用对象,多态性是同一个操作,作用到不同实例而表现出不同实现方式的特性

拿上例来说:

# 多态性
# 统一接口,归一化操作
def Speack(animal):
animal.speak()
'''
因为所有的动物都会“说”,是同一操作,但是调用的参数不同,输出的结果不同,这就是多态性的体现
''' Speack(cat)
Speack(dog)
Speack(peo) # 结果
喵喵喵
汪汪汪
啊啊啊

多态性的优点:增加的程序的扩展性,使得每次来一个实例化的对象,都是以同一种形式去调用的,多态性还增加了程序的可扩展性,通过继承父类,减少了代码的冗余

class Pig(Animal):
def speak(self):
print('哼哼哼') pig = Pig()
pig.speak()

鸭子类型



上述例子,只要是动物就可以直接使用相同的方法!多态的存在其实也限制了子类的使用方法(抽象类也是可以限制子类),定义子类的时候,必须有speak()方法,这样才能算的上动物类,所以python推荐使用“鸭子类型”,是一种不依赖于继承,也可以实现不考虑对象类型而使用对象。

class People():
def speak(self):
print('啊啊啊') class Pig():
def speak(self):
print('哼哼哼') class Dog():
def speak(self):
print('汪汪汪') def Speak(animal):
animal.speak() peo = People()
pig = Pig()
dog = Dog() Speak(peo)
Speak(pig)
Speak(dog) # 结果
啊啊啊
哼哼哼
汪汪汪

父类限制子类的行为


  • 抽象类 (abc模块)
  • 继承

主动报错示例:

'''父类限制子类'''

class Txt():
# 父类限制子类必须实现的功能
def read(self):
raise Exception("是文件就得有read功能") class Conf(Txt):
pass
# 没有实现read功能,继承报错 class Bin(Txt):
def read(self):
print('读方法') # conf = Conf()
# conf.read() # --->Exception: 是文件就得有read功能 bin = Bin()
bin.read()

组合

类和类之间代码冗余的问题可以通过继承来解决,或者super()方法等,其实我们还可以通过组合解决类与类之间代码冗余的问题

组合:一个类中以另外一个类的对象作为数据属性,就是类的组合,组合通常表示“有”的关系

class People():
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender class Course():
def __init__(self, name, period, price):
self.name = name
self.period = period
self.price = price class Student(Course, People):
def __init__(self, name, age, gender, course=None): if course is None:
course = []
self.courses = course
super().__init__(name, age, gender) # 实例化学生对象
stu = Student('HammerZe', 18, 'male') # 实例化课程对象
python = Course('python','6m',10000)
linux = Course('linux','5m',10000) # 组合
stu.courses.append(python.name)
stu.courses.append(linux.name) print(stu.courses) # ['python', 'linux']

面向对象的内置函数

  • __init__():初始化方法
  • __str__():打印对象的时候,自动触发的函数
  • __del__():在对象被删除的时候自动触发
  • __call__():对象加括号自动触发
  • __enter__():出现with语句,对象的__enter__被触发,有返回值则赋值给as声明的变量
  • __exit__():with中代码块执行完毕时执行此方法
'''__str__() \ __del__() \ __call__()'''
class Foo():
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender '''输出对象的时候打印,返回值只能是字符串'''
def __str__(self):
return '输出对象返回' '''删除对象的时候打印'''
# 1.删除对象执行
# 2.如果不删除对象,程序执行完毕也自动执行__del__()
def __del__(self):
print('删除对象执行') '''对象加括号自动触发'''
def __call__(self, *args, **kwargs):
print('对象加括号自动触发') stu = Foo('HammerZe', 18, 'male')
print(stu) # --->输出对象返回
del stu.name # --->删除对象执行
stu() # --->对象加括号自动触发
'''__enter__(),__exit__()  '''
class Open():
def __init__(self,name):
self.name = name def __enter__(self):
print('出现with语句,触发此方法,如果该方法有返回值赋值给as后面的变量')
return 123 def __exit__(self, exc_type, exc_val, exc_tb):
print('with语句执行完毕触发此方法') with Open('a.txt') as f:
pass
print(f) # --->123 # --->出现with语句,触发此方法,如果该方法有返回值赋值给as后面的变量
# --->with语句执行完毕触发此方法

反射



  • hasattr(obj,pro):按pro判断是否有无obj.pro属性
  • getattr(obj,pro,None):按pro判断是否有无obj.pro属性,没有返回None
  • setattr(obj,pro,value):设置obj.pro的值相当于obj.pro = value
  • delattr(obj,pro):删除obj.pro
class Info():
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender oneself = Info('HammerZe', 18, 'male') # 按字符串查找---hasattr
print(hasattr(oneself, 'name')) # --->True
print(hasattr(oneself, 'age')) # --->True
print(hasattr(oneself, 'gender')) # --->True # 按字符串查找---getattr
print(getattr(oneself, 'name')) # --->HammerZe
print(getattr(oneself, 'age')) # --->18
print(getattr(oneself, 'gender')) # --->male
# 查找不存在的
print(getattr(oneself, 'weight', None)) # --->None
'''None只是默认值,可以修改'''
print(getattr(oneself, 'weight', 140)) # --->140 # 按字符串修改
setattr(oneself, 'name', 'li') # 相当于oneself.name = 'li'
print(oneself.name) # --->li # 按字符串删除
delattr(oneself,'name') # 相当于del oneself.name
print(oneself.name) # --->AttributeError: 'Info' object has no attribute 'name'

python 多态、组合、反射的更多相关文章

  1. python基础-9__import__ 反射和面向对象基础 self 封装 继承(多继承顺序) 多态

    一 反射 python中的反射功能是由以下四个内置函数提供:hasattr.getattr.setattr.delattr,改四个函数分别用于对对象内部执行:检查是否含有某成员.获取成员.设置成员.删 ...

  2. 组合&反射&面向对象内置函数

    内容概要 组合 反射 面向对象的内置函数 异常 内容详细 一.组合 组合:在对象中定义一个属性,属性的值是另一个对象 除了继承父类的方法,这是获取另一个类中属性的另一种方式 如果想给学生对象添加课程属 ...

  3. python中的反射

    在绝大多数语言中,都有反射机制的存在.从作用上来讲,反射是为了增加程序的动态描述能力.通俗一些,就是可以让用户参与代码执行的决定权.在程序编写的时候,我们会写很多类,类中又有自己的函数,对象等等.这些 ...

  4. Python基础之反射

    python中的反射功能是由以下四个内置函数提供:hasattr.getattr.setattr.delattr,改四个函数分别用于对对象内部执行:检查是否含有某成员.获取成员.设置成员.删除成员. ...

  5. python面向对象进阶 反射 单例模式 以及python实现类似java接口功能

    本篇将详细介绍Python 类的成员.成员修饰符.类的特殊成员. 类的成员 类的成员可以分为三大类:字段.方法和特性. 注:所有成员中,只有普通字段的内容保存对象中,即:根据此类创建了多少对象,在内存 ...

  6. Python之路- 反射&定制自己的数据类型

    一.isinstance和issubclass isinstance(obj,cls)检查是否obj是否是类 cls 的对象 issubclass(sub, super)检查sub类是否是 super ...

  7. python的组合数据类型及其内置方法说明

    python中,数据结构是通过某种方式(例如对元素进行编号),组织在一起数据结构的集合. python常用的组合数据类型有:序列类型,集合类型和映射类型 在序列类型中,又可以分为列表和元组,字符串也属 ...

  8. Python 面向对象之反射

    Python 面向对象之反射 TOC 什么是反射? hasattr getattr setattr delattr 哪些对象可以使用反射 反射的好处 例子一 例子二 什么是反射? 程序可以访问.检查和 ...

  9. Python面向对象之-反射

    Python中一切皆对象,在Python中的反射:通过字符串的形式操作对象的属性 hasattr  判断是否有改属性或者方法,有返回True,没有返回false getattr  如果是属性获得该属性 ...

  10. Python Python中的反射机制

    Python中的反射机制 by:授客 QQ:1033553122 概念 借用java中的定义:在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方 ...

随机推荐

  1. 21.7.24 test

    \(NOIP\) 模拟赛 考差了. T1签到题.注意存在字符串长度为0,不能直接模.\(100\rightarrow0\) 代码: #include<bits/stdc++.h> usin ...

  2. .Net(c#)汉字和Unicode编码互相转换实例

    {"name": "\u676d\u5dde", "href": "www.baidu.com"} 经常遇到这样内容的j ...

  3. Latex使用CJK包添加字体

    最近写论文时有个中文期刊提供的LaTeX模板使用CJK宏包,大致是这样的: \documentclass{article} \usepackage{CJK} \begin{document} \beg ...

  4. Linux初学者:从不同角度理解Linux系统

    在我初学Linux系统时,虽然已经掌握了一些命令,但总觉得还是很混乱.大家新买的笔记本如果是Windows系统,那么第一件事往往就是分区,目的就是将系统和软件分开.然而Linux却没有类似于Windo ...

  5. Matlab 中 arburg 函数的理解与实际使用方法

    1. 理解 1.1 Matlab 帮助: a = arburg(x,p)返回与输入数组x的p阶模型相对应的归一化自回归(AR)参数. 如果x是一个向量,则输出数组a是一个行向量. 如果x是矩阵,则参数 ...

  6. 自动化SQL注入工具 sqlmap 使用手册

    0x00 sqlmap介绍 什么是sqlmap? sqlmap是一个开源的渗透测试工具,它自动化了检测和利用SQL注入缺陷 以及接管数据库服务器的过程.它配备了一个强大的检测引擎 ,以及终极渗透测试仪 ...

  7. 力扣 - 剑指 Offer 59 - I. 滑动窗口的最大值

    题目 剑指 Offer 59 - I. 滑动窗口的最大值 思路1(单调队列) 使用单调(递减)队列,保持队列中的元素是递减顺序,队列头保存的是当前窗口中最大的元素 首先先模拟建立第一个窗口,同时获取第 ...

  8. 通过大量实战案例分解Netty中是如何解决拆包黏包问题的?

    TCP传输协议是基于数据流传输的,而基于流化的数据是没有界限的,当客户端向服务端发送数据时,可能会把一个完整的数据报文拆分成多个小报文进行发送,也可能将多个报文合并成一个大报文进行发送. 在这样的情况 ...

  9. [hdu5379]Mahjong tree

    一棵子树的每一个儿子相当于划分一个区间,同时这些区间一定要存在一个点连续(直接的儿子),因此每一棵树最多只有两个儿子存在子树,并且这两个儿子所分到的区间一定是该区间最左和最右两段,所以ans*=(so ...

  10. [atARC088F]Christmas Tree

    合并具有交换律,因此即将一个连通块(初始为空)与一条链合并(其中各选1点,初始直接替换) 把插入改为染色,等价于对树上的一条链(包括点和边)染色,其中恰好有1个已经被染色的点(初始任意) 对于&quo ...