1. 多态
1.1 概念
多态指的是一类事物有多种形态
比如动物有多种形态:人、猴、鸭
1.2 代码示例
from abc import ABC, abstractmethod # 对于程序来说,定义一个基类可以有多个子类 class Animal(ABC): @abstractmethod def run(self): pass @abstractmethod def speak(self, name): print(f'{name}正在说话') # 第一种形态:人 class Person(Animal): def run(self): print('可以润') def speak(self, name): print(f'{name}正在说话') # 第二种形态:猴 class Monkey(Animal): def run(self): print('猴哥也可以润') # 第三种形态:鸭子 class Duck(Animal): def run(self): print('鸭子也可以润')
1.3 多态性
动态绑定:在程序运行的过程中,根据对象的类型,动态的将方法进行绑定
动态多样性:动态绑定在继承背景下的特性就叫动态多态性
静态多样性:如任何类型都可以用运算符加号+ 进行运算
from abc import ABC, abstractmethod # 同一类事物:动物 class Animal(ABC): @abstractmethod def run(self): pass # 第一种形态:人 class Person(Animal): def run(self): print('可以润') # 第二种形态:猴 class Monkey(Animal): def run(self): print('猴哥也可以润') # 第三种形态:鸭子 class Duck(Animal): def run(self): print('鸭子也可以润') person1 = Person() monkey1 = Monkey() duck1 = Duck() # person1、monkey1、duck1都是动物,只要是动物肯定有run方法 # 于是可以不用考虑三个对象的具体是声明类型,而直接使用 person1.run() monkey1.run() duck1.run() # 更进一步,可以定义一个统一的接口来使用 def func(obj): obj.run()
python中一切皆对象,本身就支持多态性
# 在不考虑对象类型的情况下统计对象的长度 a.__len__() b.__len__() c.__len__() # python内置了一个统一的接口 len(a) len(b) len(c)
2. 鸭子类型
鸭子类型(duck typing)是一种编程风格,不是一个真实存在的约束关系,是一种普遍的规范
看起来像、声音像、走起路来像鸭子,那么它就是鸭子
# 二者看起来都像文件,因而就可以当文件一样去用,然而它们并没有直接的关系 class Txt: # Txt类有两个与文件类型同名的方法,即read和write def read(self): pass def write(self): pass class Video: # Video类也有两个与文件类型同名的方法,即read和write def read(self): pass def write(self): pass
3. 绑定方法和非绑定方法
3.1 概念
绑定方法(动态方法):
绑定给谁,谁来调用就自动将它本身当作第一个参数传入
绑定给类的方法、绑定给对象的方法
非绑定方法(静态方法):
既不绑定给类也不绑定给对象
一句话概括:方法即函数,可以理解为绑定函数、非绑定函数
3.2 绑定给对象的方法
概述:
绑定给对象的方法就是在类内部直接定义的方法------即在类内部写的函数,写的时候自动带上self参数
特点就是会自动补全self参数
对象调用绑定给对象的方法的时候不需要传入self参数,类调用对象的绑定方法的时候需要传入self参数(对象名)
class Student: def __init__(self, name): self.name = name def run(self): # 绑定给对象的方法就是在类内部定义的方法,自动补全self对象 print(f'这是run方法,{self.name}可以润') stu1 = Student(name='lavigne') # 实例化得到的对象 # (1)对象调用对象的绑定方法 # 不需要传递self参数,在对象调用对象的绑定方法的时候会自动将对象作为self参数传进去 stu1.run() # 这是run方法,lavigne可以润 # (2)类调用对象的绑定方法 # 必须主动给self传入一个对象 stu2 = Student(name='avril') # Student.run() # 报错 TypeError: Student.run() missing 1 required positional argument: 'self' Student.run(stu1) # 这是run方法,lavigne可以润 Student.run(stu2) # 这是run方法,avril可以润
3.3 绑定给类的方法 classmethod
类在使用时会将类本身当作参数传给类方法的第一个参数(即便是对象来调用也会将类当作第一个参数传入)
classmethod把类中的函数定义成类方法
class Student: def __init__(self, name): self.name = name @classmethod def read(cls): # 绑定给类的方法,必须用classmethod装饰器,并且在定义函数的时候默认补全参数cls print(f'当前是绑定给类的read方法:{cls}') # (1)对象调用绑定给类的方法 # 不需要传入cls参数 # 会自动识别实例化当前对象的类,直接将类传入 stu1 = Student(name='lavigne') stu1.read() # 当前是绑定给类的read方法:<class '__main__.Student'> # (2)类调用绑定给类的方法 # 不需要传入cls参数 # 默认将当前类作为cls的默认参数传入 Student.read() # 当前是绑定给类的read方法:<class '__main__.Student'>
总结:
定义绑定给类的方法的时候,必须用装饰器@classmethod;类似于绑定给对象的方法函数,会自动补全参数cls
对象调用绑定给类的方法,不需要传入cls参数
类调用绑定给类的方法,不需要传入cls参数
3.4 非绑定方法 staticmethod
在类内部用staticmethod装饰的函数即非绑定方法,就是普通函数
staticmethod既不绑定给类,也不绑定给对象,在定义函数的时候和普通函数一样不会补全任何默认参数
标签:run,22,对象,self,绑定,多态,面向对象,方法,def From: https://www.cnblogs.com/hbutmeng/p/18363425