多态 , 绑定方法与内置方法
1.3多继承
class DingYuan :
def __init__ ( self) :
self. fatherName = "丁原义父"
def setOffices ( self) :
print ( "升官为主簿" )
class DongZhuo :
def __init__ ( self) :
self. fatherName = "董卓义父"
def setOffices ( self) :
print ( "送赤兔马" )
class WangYun :
def __init__ ( self) :
self. fatherName = "王允义父"
def setOffice ( self) :
print ( "送貂蝉" )
class LvBu ( DingYuan, WangYun , DongZhuo) :
def __init__ ( self) :
super ( LvBu, self) . __init__( )
def setOffices ( self) :
WangYun. setOffice( self)
DongZhuo. setOffices( self)
DingYuan. setOffices( self)
lvbu = LvBu( )
lvbu. setOffices( )
print ( LvBu. __mro__)
print ( DongZhuo. __mro__)
print ( LvBu. __bases__)
print ( lvbu. fatherName)
2、多态
一个对象的多种状态
不同的对象,调用同一个方法,表现出不同形式
多态的实现遵守两个原则:1.必须要有类的继承 2.子类必须重写父类的方法
什么时候多态
怎么方便怎么来
class Money :
def ticke ( self) :
print ( "车票单价" )
class Car ( Money) :
def ticke ( self) :
print ( "票价是200元" )
class Bus ( Money) :
def ticke ( self) :
print ( "票价150元" )
class Train ( Money) :
def ticke ( self) :
print ( "票价120元" )
c = Car( )
b = Bus( )
t = Train( )
c. ticke( )
b. ticke( )
t. ticke( )
二 、绑定方法
1、绑定(类方法)
类方法, 通过装饰器@classmethod 进行装饰,绑定类cls
类方法操作一定是类属性,因为类方法无法通过self去获取对象属性
class Student :
number = 0
def __init__ ( self, name) :
self. name = name
def sleep ( self) :
print ( f" { self. name} 在睡觉" )
@classmethod
def count ( cls) :
cls. number += 1
return cls. number
student1 = Student( "笑脸" )
Student. count( )
student2 = Student( "小虎同学" )
Student. count( )
student3 = Student( "无风柳自断" )
Student. count( )
student4 = Student( "爱丽丝" )
Student. count( )
print ( Student. number)
student5 = Student( "学员1909" )
student5. count( )
print ( Student. number)
2、静态方法(非绑定)
静态方法:通过装饰器@staticmethod进行装饰,为了方便代码统一管理,把类外面的某一个功能函数统一放到类里面管理,静态方法不能操作类的所有东西包括对象也是一样
单纯的一个方法:比如单纯的输出文字,单纯的计算某些数值,不改变任何属性
一句话,不需要用self,或者cls进行操作的都可以变成静态方法
import time
class Student :
number = 0
def __init__ ( self, name) :
self. name = name
def sleep ( self) :
print ( f" { self. name} 在睡觉" )
@classmethod
def count ( cls) :
cls. number += 1
return cls. number
@staticmethod
def setTime ( ) :
print ( f" { time. strftime( '%Y-%m-%d' ) } " )
student1 = Student( "笑脸" )
Student. count( )
student2 = Student( "小虎同学" )
Student. count( )
student3 = Student( "无风柳自断" )
Student. count( )
student4 = Student( "爱丽丝" )
Student. count( )
print ( Student. number)
student5 = Student( "学员1909" )
student5. count( )
print ( Student. number)
student5. setTime( )
3、检查类型
type() # 查询单个数据类型
类如何查询类型
查询对象是否有指定的类生成 isinstance(obj/对象, cls/类)
查询是否有继承关系 issubclass(cls/子类,class_tuple/父类)
import time
class Student :
number = 0
def __init__ ( self, name) :
self. name = name
def sleep ( self) :
print ( f" { self. name} 在睡觉" )
@classmethod
def count ( cls) :
cls. number += 1
return cls. number
@staticmethod
def setTime ( ) :
print ( f" { time. strftime( '%Y-%m-%d' ) } " )
student1 = Student( "笑脸" )
Student. count( )
student2 = Student( "小虎同学" )
Student. count( )
student3 = Student( "无风柳自断" )
Student. count( )
student4 = Student( "爱丽丝" )
Student. count( )
print ( Student. number)
student5 = Student( "学员1909" )
student5. count( )
print ( Student. number)
student5. setTime( )
print ( isinstance ( student5, Student) )
print ( issubclass ( Student, object ) )
三、内置方法
1.信息格式化方法
__str__该方法用户可以直接打印对象名来获取对象的描述,或者返回设计文本
class demo1 :
def __init__ ( self, name, age) :
self. name = name
self. age = age
def __str__ ( self) :
return f"这个是 { self. name} 的对象"
a = demo1( "大聪明" , 16 )
print ( a)
2. 析构方法(魔法方法)
__del__ 当检测到对象每一继续被引用时,会自动删除对象所占用的内存空间
就算一大段代码没有涉及到对象的运用,也不会先自动删除,因为后面都有可能被引用对象
对象被间接赋值到另一个变量的时候,不能确保这个变量后续有没有继续被引用,那么不会删除
class Student :
def __init__ ( self, name) :
self. name = name
def func ( self) :
print ( f" { self. name} 我还活着" )
def __del__ ( self) :
print ( f" { self. name} gg了" )
student1 = Student( "海绵宝宝" )
student1. func( )
print ( student1)
studentTest = student1
studentTest. func( )
print ( "-" * 100 )
print ( "-" * 100 )
print ( "-" * 100 )
print ( "-" * 100 )
__new__是内置的静态类方法,主要是给实例化对象分配内存空间,返回一个对象引用
python解析器在得到这个方法之后,会将引用作为第一个参数传递给init使用
如果没有返回值,python解析器没有获取对象的引用,就是创建不成功
new必须有返回值
拓展:
new和init的相同点和不同点
相同点: 都可以实例化进行初始化
不同点:new不仅仅可以开辟内存空间吗,也可以实例化属性,init只能实例化对象,不能开辟内存空间
如果没有new设计约束,那么对象是可以无限创建,如果你想约束对象个数,要通过new进行约束
class A :
def __new__ ( cls, * args, ** kwargs) :
print ( "给一个实例化对象分配一个内存空间" )
return super ( ) . __new__( cls)
def __init__ ( self, name, age) :
self. name = name
self. age = age
a1 = A( "xxx" , 12 )
a2 = A( "xxx" , 12 )
a3 = A( "xxx" , 12 )
a4 = A( "xxx" , 12 )
a5 = A( "xxx" , 12 )
class A :
__instance = None
def __new__ ( cls, * args, ** kwargs) :
if cls. __instance is None :
cls. __instance = super ( ) . __new__( cls)
return cls. __instance
def __init__ ( self, name, age) :
self. name = name
self. age = age
a1 = A( "梓良" , 12 )
print ( a1. name)
a2 = A( "xxx1" , 15 )
print ( a2. name)
class A:
# 开始约束对象个数:1个 -》单例模式
# 隐藏类属性
# 这个有什么作用:做一个内存标志,None代表有空余的内存空间
# 如果有对象数据,就代表没有这个内存空间
# 为啥设置隐藏属性,就是只需要类内部操作,对象和外部不能操作
__instance = None
__count = 1
def __new__(cls, *args, **kwargs):
if cls.__instance is None or cls.__count <= 3 :
# super().__new__(cls) 这个就是返回创建对象的数据, 这里就是创建对象的意思
# cls.__instance = super().__new__(cls) 代表对象已经占用内层
cls.__instance = super().__new__(cls)
cls.__count += 1
return cls.__instance
def __init__(self, name, age):
self.name = name
self.age = age
a1 = A("梓良", 12)
print(a1.name)
# 这里应该会报错
a2 = A("xxx1", 15)
print(a2.name)
# 这里应该会报错
a3 = A("xxx2", 15)
print(a3.name)
# 这里应该会报错
a4 = A("xxx3", 15)
print(a4.name)