多继承及魔术方法介绍

多继承弊端

多继承的弊端会造成菱形继承这种情况,找不清调用顺序
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)时的行为
...
...
''' 
posted @ 2021-05-19 22:37  urls  阅读(45)  评论(0编辑  收藏  举报