多态与多态性

多态

多态并不是一个新的知识

多态是指一类事物有多种形态,在类里就是指一个抽象类有多个子类,因而多态的概念依赖于继承

举个栗子:动物有多种形态,人、狗、猫、猪等,python的序列数据类型有字符串、列表、元组,文件的类型分为普通文件和可执行文件,人类又有多种形态,男女老少。。等等例子

 import abc
class Animal(metaclass=abc.ABCMeta): #模拟动物类
@abc.abstractmethod
def talk(self):
pass
class People(Animal): #模拟人类
def talk(self):
print('say hello world')
class Cat(Animal): #模拟猫类
def talk(self):
print('say miaomiaomiao')
class Dog(Animal): #模拟狗类
def talk(self):
print('say wangwangwang')

动物都能叫,所以人类、猫类、狗类也都可以叫,只不过叫的方式不一样。

多态性:

多态性是指具有不同功能的函数可以使用相同的函数名,这样就可以用一个函数名调用到不同功能的函数。

在面向对象方法中一般是这样表述多态性:向不同的对象发送同一条消息(!!!obj.func():是调用了obj的方法func,又称为向obj发送了一条消息func),不同的对象在接收时会产生不同的行为(即方法)

多态性实际上就是一个接口,即调用同一个函数,产生不同的结果。

示例1:使用数据对象的__len__属性统计对象长度

 def func(obj):
obj.__len__()
func('hello')
func([1,2,3,4])
func(('a','b','c'))

示例2:

 import abc
class Animal(metaclass=abc.ABCMeta): #模拟动物类
@abc.abstractmethod
def talk(self):
pass
class People(Animal): #模拟人类
def talk(self):
print('say hello world')
class Cat(Animal): #模拟猫类
def talk(self):
print('say miaomiaomiao')
class Dog(Animal): #模拟狗类
def talk(self):
print('say wangwangwang') p1=People()
c1=Cat()
d1=Dog() def talk(obj): #多态性
obj.talk()
talk(p1)
talk(c1)
talk(d1)

多态性的优点1:以不变应万变,统一调用接口,使用者只用一种调用方式即可

多态性的优点2:增加扩展性,比如上述代码再加一个Pig类,调用talk功能的方式不会改变,就是talk(Pig对象)

绑定方法与非绑定方法

类中定义的函数分为两类:绑定方法和非绑定方法

绑定方法:绑定给谁就给谁用,可以是对象,也可以是类本身。

绑定到对象的方法:

  定义:凡是在类中定义的函数(没有被任何装饰器修饰),都是绑定给对象的,无论有有没有传参

  给谁用:给对象用

  特点:例如obj.bar() 自动把obj当做第一个参数传入,因为bar中的逻辑就是要处理obj这个对象

示例:

 class People:
def __init__(self, name, weight, height):
self.name = name
self.weight = weight
self.height = height
def bmi(self): #绑定到对象,需要传入对象的名字,而类本身是无法使用的,如果硬要使用,也需要把对象名字传进来
print(self.weight / (self.height ** 2))
f = People('bob', 70, 1.80)
f.bmi() #绑定对象使用的方法
People.bmi(f) #类使用需要传入对象名字

绑定到类的方法:

  定义:在类中定义的,被classmethod装饰的函数就是绑定到类的方法

  给谁用:给类用

  特点:例如People.talk() 自动把类当做第一个参数传入,因为talk中的逻辑就是要处理类

注意:自动传值只是使用者意淫的,属于类的函数,类可以调用,但是必须按照函数的规则来,在任何过程中都没有自动传值那么一说,传值都是事先定义好的,只不过使用者感知不到。

示例1:

 class People:
def __init__(self,name):
self.name=name
def bar(self):
print('Object name:',self.name)
@classmethod #将方法绑定给类People
def func(cls): #传入的值只能是类的名字
print('Class name:',cls)
f=People('natasha')
print(People.func) #绑定给类
print(f.bar) #绑定给对象
People.func() #类调用绑定到类的方法
f.func() #对象调用绑定到类的方法,打印的依然是类的名字

输出结果:

 <bound method People.func of <class '__main__.People'>>    #绑定到类的方法
<bound method People.bar of <__main__.People object at 0x0000026FC4109B38>> #绑定到对象的方法
Class name: <class '__main__.People'> #类调用返回类名
Class name: <class '__main__.People'> #对象调用返回类名

非绑定方法:

用staticmethod装饰器装饰的方法,非绑定方法不与类或对象绑定,类和对象都可以调用,但是没有自动传值那么一说。就是一个普通工具而已

注意:没有传值的普通函数并不是非绑定方法,只有被staticmethod装饰的才是非绑定方法。

示例

 import hashlib
import pickle
import os
# 模拟注册,生成一个唯一id标识
student_path=r'C:\Users\Mr.chai\Desktop\PythonProject\笔记\2017.7.6\db' class People:
def __init__(self,name,sex,user_id):
self.name=name
self.sex=sex
self.user_id=user_id
self.id=self.create_id()
def tell_info(self): #打印所有信息
print('''
=====%s info=====
id:%s
name:%s
sex:%s
user_id:%s
''' %(self.name,self.id,self.name,self.sex,self.user_id))
def create_id(self): #生成一个id号,对name、sex和user_id进行哈希
m=hashlib.md5()
m.update(self.name.encode('utf-8'))
m.update(self.sex.encode('utf-8'))
m.update(str(self.user_id).encode('utf-8'))
return m.hexdigest()
def save(self): #将id号序列化到文件,以id号为文件名字
idfile_path=student_path+'\\'+self.id
with open(idfile_path,'wb') as f:
pickle.dump(self,f)
@staticmethod #反序列化程序,是一个非绑定方法,无关类和对象
def get_all():
res=os.listdir(student_path)
for item in res:
file_path = r'%s\%s' %(student_path,item)
with open(file_path,'rb') as f:
obj = pickle.load(f)
obj.tell_info()

测试:生成序列化文件

 #实例化对象
p1=People('natasha','male',370283111111111111)
p2=People('hurry','male',3702832222222222222)
p3=People('bob','male',3702833333333333333)
#查询唯一标识
print(p1.id)
print(p2.id)
print(p3.id)
#对象pickle序列化
p1.save()
p2.save()
p3.save() 查询输出:
b4ea1e1f1e45428ee16035e101caac7b
274496ab60ceea8bf4c89c841d2b225c 0defdb74fdee00f2164839343c16a7d7

生成文件

反序列化:

 p1.get_all()
# p2.get_all()
# p3.get_all() 输出结果 =====bob info=====
id:0defdb74fdee00f2164839343c16a7d7
name:bob
sex:male
user_id:3702833333333333333 =====hurry info=====
id:274496ab60ceea8bf4c89c841d2b225c
name:hurry
sex:male
user_id:3702832222222222222 =====natasha info=====
id:b4ea1e1f1e45428ee16035e101caac7b
name:natasha
sex:male
user_id:370283111111111111

绑定到类的方法应用

Python开发基础-Day21多态与多态性、绑定方法和非绑定方法的更多相关文章

  1. Python开发基础-Day20继承实现原理、子类调用父类的方法、封装

    继承实现原理 python中的类可以同时继承多个父类,继承的顺序有两种:深度优先和广度优先. 一般来讲,经典类在多继承的情况下会按照深度优先的方式查找,新式类会按照广度优先的方式查找 示例解析: 没有 ...

  2. python基础之多态与多态性、绑定方法和非绑定方法

    多态与多态性 多态 多态并不是一个新的知识 多态是指一类事物有多种形态,在类里就是指一个抽象类有多个子类,因而多态的概念依赖于继承 举个栗子:动物有多种形态,人.狗.猫.猪等,python的序列数据类 ...

  3. Python--多态与多态性、绑定方法与非绑定方法

    多态与多态性 多态 多态指的是一类事物有多种形态,(一个抽象类有多个子类,因而多态的概念依赖于继承) 1. 序列类型有多种形态:字符串,列表,元组. s='hello' l=[,,] t=('a',' ...

  4. 1.面向过程编程 2.面向对象编程 3.类和对象 4.python 创建类和对象 如何使用对象 5.属性的查找顺序 6.初始化函数 7.绑定方法 与非绑定方法

    1.面向过程编程 面向过程:一种编程思想在编写代码时 要时刻想着过程这个两个字过程指的是什么? 解决问题的步骤 流程,即第一步干什么 第二步干什么,其目的是将一个复杂的问题,拆分为若干的小的问题,按照 ...

  5. salesforce lightning零基础学习(三) 表达式的!(绑定表达式)与 #(非绑定表达式)

    在salesforce的classic中,我们使用{!expresion}在前台页面展示信息,在lightning中,上一篇我们也提及了,如果展示attribute的值,可以使用{!v.expresi ...

  6. 全面解析python类的绑定方法与非绑定方法

    类中的方法有两类: 绑定方法 非绑定方法 一.绑定方法 1.对象的绑定方法 首先我们明确一个知识点,凡是类中的方法或函数,默认情况下都是绑定给对象使用的.下面,我们通过实例,来慢慢解析绑定方法的应用. ...

  7. python绑定调用和非绑定调用

    绑定调用和非绑定调用 在python中,绑定调用和非绑定调用其实是相对于类和实例来说的.抽象点说就是:在类实例化过程中,类的方法会绑定在实例之中,此时,这个实例会拥有这个类的具体属性和方法,这些属性和 ...

  8. Python面向对象之封装、property特性、绑定方法与非绑定方法

    一.封装 ''' 1.什么封装 封:属性对外是隐藏的,但对内是开放的(对内是开放的是因为在类定义阶段这种隐藏已经发生改变) 装:申请一个名称空间,往里装入一系列名字/属性 2.为什么要封装 封装数据属 ...

  9. 类的封装,property特性,类与对象的绑定方法和非绑定方法,

    类的封装 就是把数据或者方法封装起来 为什么要封装 封装数据的主要原因是:保护隐私 封装方法的主要原因是:隔离复杂度(快门就是傻瓜相机为傻瓜们提供的方法,该方法将内部复杂的照相功能都隐藏起来了,比如你 ...

随机推荐

  1. Python编写在Maya中查看文件列表的插件

    之前写过一篇用Python遍历文件夹的文章,今天把代码扩展一下,做成一个有UI用户界面的Maya插件,可以直接在Maya中运行: 功能是显示磁盘分区目录下的文件列表,通过定制也可以查看任意目录下的文件 ...

  2. TOJ 1049 Jesse's problem (最短路 floyd)

    描述 All one knows Jesse live in the city , but he must come to Xiasha twice in a week. The road is to ...

  3. elementui table 多选 获取id

    //多选相关方法 toggleSelection(rows) { if (rows) { rows.forEach(row => { this.$refs.multipleTable.toggl ...

  4. ctsc&apio2018八日游

    day0: 早就知道自己是打酱油的..早就做好了打铁的准备.. Q:那你来干嘛 A:当然是来玩啊!!玩啊!啊!! emmmmm 抱着半期考不及格的卷子瑟瑟发抖地上了飞机. day1:报道!当然还有在宾 ...

  5. js 实时显示字数

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. nodejs 优雅的连接 mysql

    1.mysql 及 promise-mysql nodejs 连接 mysql 有成熟的npm包 mysql ,如果需要promise,建议使用 promise-mysql: npm:https:// ...

  7. CentOS下配置FTP

    http://www.cnblogs.com/zhenmingliu/archive/2012/04/25/2470646.html 常见错误: 1.FTP服务器已经拒绝 解决方案 # setenfo ...

  8. HDU 3480 Division(斜率DP裸题)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3480 题目大意:将n个数字分成m段,每段价值为(该段最大值-该段最小值)^2,求最小的总价值. 解题思 ...

  9. 共享变量 static

    一个类,有static变量counter,所有类实例共享 如果多个类实例,通过多线程访问static变量,就会产生覆盖的情况. 会发现counter偏小. 解决方法: AtomicLong count ...

  10. DataTable.DefaultView.Sort 排序方法

    今天在整合一个东西,需要用到DataTable的一个排序方法, 前我是将DataTable存到DataView里面的,所以刚开始就使用了DataView.Sort="ColumnName A ...