多继承及魔术方法介绍
多继承的弊端会造成菱形继承这种情况,找不清调用顺序
super对象按照mro列表的顺序依次调用,解决菱形继承存在的问题
经典类:深度优先 (python2.x)
新式类:广度优先 (python3.x)
写多继承时,尽量避免造成不同类相同方法名的情况,提高代码质量 高内聚,低耦合
高内聚:一个模块只完成一个任务,专一性高
低耦合:模块与模块之间可以彼此独立不冲突,方便移植复用.
super调用父类方法
(1)super本身是一个类 super()是一个对象 用于调用父类的绑定方法
(2)super() 只应用在绑定方法中,默认自动传递self对象 (前提:super所在作用域存在self)
(3)super用途: 解决复杂的多继承调用顺序
魔术方法(特定时机自动触发)
__init__魔术方法(构造方法)
'''
触发时机:实例化对象,初始化的时候触发
功能:为对象添加成员
参数:参数不固定,至少一个self参数
返回值:无
'''
示例:
# (1) 基本语法 class MyClass(): def __init__(self): print("构造方法被触发 ... ") self.color = "屎黄色" # 在类内为对象添加成员 # 实例化对象 obj = MyClass() print(obj.__dict__) 结果:{'color':'屎黄色'} print(obj.color) 结果: 屎黄色 # (2) 带有多个参数的构造方法 class MyClass(): def __init__(self,color): self.color = color # 实例化对象 obj1 = MyClass("狗屎绿") print(obj1.color) obj2 = MyClass("粉嫩红") print(obj2.color) # (3)类可以是一个,对象可以是多个,创造的对象彼此是独立的; class Children(): def __init__(self,name,skin): self.name = name self.skin = skin def cry(self): print("小孩一下生久哇哇哇的哭") def la(self): print("小孩一下生久拉粑粑") def __eat(self): print("小孩一下生就要吃奶奶..") def info(self): print("小孩的名字:{},小孩的肤色{}".format(self.name,self.skin)) def info2(self,name,skin): print("小孩的名字:{},小孩的肤色{}".format(name,skin)) # 实例化对象 afanda = Children("阿凡达","深蓝色") afanda.cry() afanda.info() haoke = Children("绿巨人","绿色的") haoke.la() haoke.info() wangbaoqiang = Children("王宝强","亮绿色") wangbaoqiang.info() # wangbaoqiang.__eat() error wangbaoqiang.info2("张保张","黄色")
#__call__ 魔术方法
'''
触发时机:把对象当作函数调用的时候自动触发
功能: 模拟函数化操作
参数: 参数不固定,至少一个self参数
返回值: 看需求
'''
示例:
# (1) 基本语法 class MyClass(): def __call__(self): print("__call__魔术方法被触发 ... ") obj = MyClass() obj() # (2) 利用__call__魔术方法做统一调用 class Wash(): def __call__(self,something): print("我要洗{}".format(something)) self.step1(something) self.step2() self.step3() return "洗完了" def step1(self,something): print("放水,把{}扔进去".format(something)) def step2(self): print("倒洗衣粉,洗衣液,蓝月亮,金纺,立白 ... ") def step3(self): print("洗一洗,晾干,穿上") obj = Wash() # obj.step1() # obj.step2() # obj.step3() res = obj("袜子") print(res) # (3) 模拟整型强转操作 import math class MyInt(): def __call__(self,num): if isinstance(num,bool): if num == False: return 0 else: return 1 elif isinstance(num,int): return num elif isinstance(num,float): # 方法一 # a,b = str(num).split(".") # return eval(a) # 方法二 """ if num >= 0: return math.floor(num) else : return math.ceil(num) """ # 简写 return math.floor(num) if num >= 0 else math.ceil(num) elif isinstance(num,str): if (num[0] == "+" or num[0] == "-") and num[1:].isdecimal(): # 获取当前字符串的正负值 if num[0] == "+": sign = 1 elif num[0] == "-": sign = -1 # 截取符号后面的字符串传递 return self.calc(num[1:],sign) elif num.isdecimal(): return self.calc(num) else: return "这个算不了兄弟~" # 计算最后的数值 def calc(self,num,sign=1): # 去掉前面的"0"字符串 num = num.lstrip("0") # print(num , type(num) , "<==============>") if num == "": return 0 return eval(num) * sign myint = MyInt() res = myint(-5.67) print(res , type(res)) res = myint("-000000000000055555") print(res , type(res)) res = myint("asdfasdfasdfasdf") print(res , type(res)) # print(myint("+0000000000000")) # bool int float 纯数字字符串 # int(3.78) => 3 # print(int(-3.78)) # import math # print(math.floor(0) ) # => 3 # print(math.ceil(0)) """ print( int("00000000000001223") ) # 1223 print( int("-00000000000001223") ) # -1223 print( int("+00000000000001223") ) # 1223 print( int("+0000000000000") ) # 1223 """ # print( int("asdfasdfasdfasdf") ) # 1223 # print( eval("00000000000001223") ) # print( eval("+00000000000001223") ) # print( eval("-00000000000001223") ) # print( eval("-00000000000001223abc") )
#__str__ 魔术方法
'''
触发时机: 使用print(对象)或者str(对象)的时候触发
功能: 查看对象
参数: 一个self接受当前对象
返回值: 必须返回字符串类型
'''
示例:
class Cat(): gift = "抓老鼠" # 类属性 def __init__(self,name): self.name = name # 对象属性 def cat_gift(self): return "小猫叫{},小猫会{}".format(self.name,self.gift) def __str__(self): return self.cat_gift() __repr__ = __str__ tom = Cat("汤姆") # 触发时机1 : print(对象) # print(tom) # 触发时机2 : str(对象) res = str(tom) print(res)
结果:
小猫叫汤姆,小猫会抓老鼠 print("<==================>") res = repr(tom) print(res , type(res)) print("<==================>") # ### __repr__ 魔术方法 ''' 触发时机: 使用repr(对象)的时候触发 功能: 查看对象,与魔术方法__str__相似 参数: 一个self接受当前对象 返回值: 必须返回字符串类型 ''' class Mouse(): gift = "偷油吃" def __init__(self,name): self.name = name def mouse_gift(self): return "老鼠叫{},老鼠会{}".format(self.name,self.gift) def __repr__(self): return self.mouse_gift() # 系统底层默认把__repr__方法赋值给__str__方法,所以通过print或者str强转可以触发; # __str__ = __repr__ jerry = Mouse("杰瑞") # res = repr(jerry) # print(res) # 可以触发 # print(jerry) res = str(jerry) print(res)
结果:
老鼠叫杰瑞,老鼠会偷油吃
#__repr__ 魔术方法
'''
触发时机: 使用repr(对象)的时候触发
功能: 查看对象,与魔术方法__str__相似
参数: 一个self接受当前对象
返回值: 必须返回字符串类型
'''
#----普通变量的基本操作,如果应用在对象上,也有相应的魔术方法
#__bool__ 魔术方法
'''
触发时机:使用bool(对象)的时候自动触发
功能:强转对象
参数:一个self接受当前对象
返回值:必须是布尔类型
'''
'''
类似的还有如下等等(了解):
__complex__(self) 被complex强转对象时调用
__int__(self) 被int强转对象时调用
__float__(self) 被float强转对象时调用
...
...
'''
#__add__ 魔术方法 (与之相关的__radd__ 反向加法)
'''
触发时机:使用对象进行运算相加的时候自动触发
功能:对象运算
参数:二个对象参数
返回值:运算后的值
'''
'''
类似的还有如下等等(了解):
__sub__(self, other) 定义减法的行为:-
__mul__(self, other) 定义乘法的行为:
__truediv__(self, other) 定义真除法的行为:/
...
...
'''
#__len__ 魔术方法
'''
触发时机:使用len(对象)的时候自动触发
功能:用于检测对象中或者类中某个内容的个数
参数:一个self接受当前对象
返回值:必须返回整型
'''
'''
类似的还有如下等等(了解):
__iter__(self) 定义迭代容器中的元素的行为
__reversed__(self) 定义当被 reversed() 调用时的行为
__contains__(self, item) 定义当使用成员测试运算符(in 或 not in)时的行为
...
...
'''