• del,str,repr,call,bool,add,len等魔术方法以及与类相关的魔术属性---day23


    1.__del__

    # ### __del__魔术方法(析构方法)
    '''
            触发时机:当对象被内存回收的时候自动触发(1.页面执行完毕回收所有变量2.所有对象被del的时候)
            功能:对象使用完毕后资源回收
            参数:一个self接收对象
            返回值:无
    '''
    class LangDog():
        food = "吃肉"
        def __init__(self,name):
            self.name = name
            
        def __del__(self):
            print("析构方法被触发")
    #(1) 页面执行完毕回收所有变量
    obj= LangDog("刀疤")
    print(obj.name)
    '''
    打印结果:
    刀疤
    析构方法被触发
    '''
    
    #(2)所有对象被del的时候
    '''
    当一个值,没有任何变量指向或者说引用,这个值才会被真正的释放
    '''
    other_obj =  obj
    print(other_obj is obj) #True
    del obj #如果只删除这一个的话,那么就不会执行del方法
    del other_obj
    '''
    打印结果:
    True
    析构方法被触发
    '''
    
    #模拟文件操作
    '''
    fp = open(文件,模式,编码)
    fp.read()
    fp.close()
    '''
    import os
    class ReadFile():   
        def __new__(cls,filename):  #创建的时候就进行判断文件存在或不存在
            #判断文件是否存在
            if os.parh.exists(filename):
                return object.__new__(cls)
            else:
                print("文件不存在")
            
        def __init__(self,filename):  #初始化对象的时候就进行打开文件操作
            self.fp = open(filename,'r',encoding='utf-8')
            
        def readcontent(self):#读文件内容方法
            content = self.fp.read()
            return content
        
        def __del__(self):   #资源回收的时候关闭文件
            self.fp.close()
    
    obj = ReadFile("ceshi.txt")
    res = obj.readcontent()
    print(res)

    2.__str__和__repr__

    #  __str__ 魔术方法
    '''
        触发时机:使用print(对象)或者str(对象)的时候触发
        功能:查看对象
        参数:一个self接收当前对象
        返回值:必须返回字符串类型
    '''
    class Cat():
        gift = "传说中的小猫有九条命,喜欢卖萌和上树"
        
        def __init__(self,name):
            self.name = name
            
        def __str__(self):
            return self.cat_info()
            
        def cat_info(self):
            return "{}小猫有故事--{}".format(self.name,self.gift)
            
    tom = Cat("汤姆")
    #触发方式一。print打印该对象
    print(tom)
    #触发方式二,str转换对象
    res = str(tom)
    print(res)
    
    
    # __repr__ 魔术方法
    '''
        触发时机:使用repr(对象)的时候触发
        功能:查看对象,与魔术方法__str__相似
        参数:一个self接收当前对象
        返回值:必须返回值是字符串类型
    '''
    class Mouse():
        gift = '打洞'
        
        def __init__(self,name):
            self.name = name
            
        def __repr__(self):
            return self.mouse_info()
            
        def mouse_info(self):
            return "{}老鼠天赋是{},龙生龙,凤生凤,老鼠的儿子会打洞".format(self.name,self.gift)
            
        #在系统底层,如果定义了repr,将会默认赋值给str方法
        #__str__ =  __repr__
    
    #repr 强转obj对象时触发
    obj = Mouse()
    res = repr(obj)
    print(res)
    
    #注意点 底层存在赋值调用给str的语法,所以能实现打印或者str强转对象的触发机制
    print(obj)
    res = str(obj)
    print(rs)
    #也就是如果先用的repr方法,那么可以也用str转
    #但是如果先用的str方法,那么就不能用repr方法转

    3.__call__

    # ### __call__ 魔术方法
    '''
        触发时间:把对象当做函数调用的时候自动触发
        功能:模拟函数化操作
        参数:参数不固定,至少一个self参数
        返回值:看需求
    '''
    #(1) 基本用法
    class MyClass():    
        a = 1
        
        def __call__(self):
            print("call魔术方法被触发")
    obj = MyClass()
    obj()
    
    #(2) 模拟洗衣服的过程
    class Wash():
        #用call魔术方法统一调用  当实例化对象后加()当成函数用时触发下面
        def __call__(self,something):
            self.step1(something)
            self.step2()
            self.step3()
            
        def step1(self,something):
            print("脱衣服,洗{}".format(something))
            
        def step2(self):
            print("放水里,扔点洗衣液,洗衣粉,蓝月亮")
            
        def step3(self):
            print("扭干净,穿上")
    obj = Wash()
    obj('裤衩')
    
    #(3)模拟内置方法 int 实现myint
    import math
    class MyInt():
        
        def mycalc(self,num,sign = 1):
            #去掉左边多余的0
            strvar = num.lstrip("0")
            if strvar == '':
                return 0
            #计算最终结果
            return eval(strvar) * sign
            
        def __call__(self,num):
            #判断是布尔类型
            if isinstance(num,bool):
                if num == True:
                    return 1
                else:   
                    return 0
            
            #判断是整型
            elif isinstance(num,int):
                return num
            
            #判断是浮点型
            elif isinstance(num,float):
                #方法一
                '''
                strvar = str(num)
                return strvar.split(".")[0]
                '''
                #方法二
                '''
                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
                    else:   
                        sign = -1
                    return self.mycalc(num[1:],sign)
                
                elif num.isdecimal():
                    return self.mycalc(num)
                else:
                    retun "老铁,这个真不能转"
    
    myint = MyInt()
    print(  myint(0)  ) #=> 3
    print(  myint(3.13)  ) #=> 3
    print(  myint("+00000000000000000001003")  ,"<==1=>")
    print(  myint("+abcd")  ,"<===>")
    print(  myint("-0000000000000000000.1003")  ,"<==2=>")
    print(  int("0000000000000000000003")  )
    print(  int("+0000000000000000000003")  )
    # print(  int("+-+-+-+-+-+-1233444")  )
    print(  myint("+-+-+-+-+-+-1233444")  )

    4.__bool__,__add__,__len__

    # ### __bool__
    '''
        触发时机:使用bool(对象)的时候自动输出
        功能:强转对象
        参数:一个self接收当前对象
        返回值:必须是布尔类型
    '''
    '''
    #类似的还有如下等等(了解):
        __complex__(self)      被complex强转对象时调用
        __int__(self)          被int强转对象时调用
        __float__(self)        被float强转对象时调用
    '''
    class MyClass():
        def __bool__(self):
            return True
    obj = MyClass()
    res = bool(obj)
    print(res) #True
    
    
    #__add__ 魔术方法(与之相关的__radd__反向加法)
    '''
        触发时机:使用对象进行运算相加的时候自动触发
        功能:对象运算
        参数:二个对象参数
        返回值:运算后的值
    '''
    '''
    类似的还有如下等等(了解):
        __sub__(self, other)           定义减法的行为:-
        __mul__(self, other)           定义乘法的行为:
        __truediv__(self, other)       定义真除法的行为:/
    '''
    class MyAdd():
        def __init__(self,num):
            self.num = num
            
        #对象在加号+左侧的时候,自动触发
        def __add__(self,other):
            return self.num + other
            
        def _radd__(self,other):
            return self.num + other * 2
            
    #情况一
    a = MyAdd(7)
    #self 接收a other接收7  触发的是__add__方法
    #情况二
    #res = a + 7
    #self 接收a other接收7  触发的是__radd__方法
    #res = 7 + a
    #print(res)
    #情况三
    '''
    a + b 先触发 __add__,self 接收的是7,other接收的是b
    res = 7 + b
    
    7 + b 再触发 __radd__,self接收的是b,other接收的是7
    return 8 + 7*2 = 22
    res = 22
    '''
    b = MyAdd(8)
    res = a + b
    print(res)
    
    #__len__ 魔术方法
    '''
        触发时机:使用len(对象)的时候自动触发
        功能:用于检测对象中或者类中成员的个数
        参数:一个self接收当前对象
        返回值:必须返回整型
    '''
    '''
    类似的还有如下等等(了解):
        __iter__(self)                 定义迭代容器中的元素的行为
        __reversed__(self)             定义当被 reversed() 调用时的行为
        __contains__(self, item)       定义当使用成员测试运算符(in 或 not in)时的行为
    '''
    
    #计算一下类中所有自定成员的个数
    class MyClass():
        pty1 = 1
        pty2 = 2
        __pty3 = 3
        
        def func1():
            pass
            
        def func2():
            pass
        
        def func3():
            pass
        
        def func4():
            pass
        
        def __len__(self):
            #print(MyClass.__dict__)
            #lst = []
            #for i in MyClass.__dict__:
                #print(i)
                #if not(i.startswith("__") and i.endswith("__")):
                    #lst.append(i)
            #print(lst)
            #简写
            lst = [i for i in MyClass.__dict__ if not (i.startswith("__") and  i.endswith("__"))]
            return  len(lst)
    obj = MyClass()
    print(len(obj))
    
    """
    {
    '__module__': '__main__',
     'pty1': 1, 
     'pty2': 2, 
     '_MyClass__pty3': 3, 
     'func1': <function MyClass.func1 at 0x000001FFAF8C4840>, 
     'func2': <function MyClass.func2 at 0x000001FFAF8C48C8>, 
     '_MyClass__func3': <function MyClass.__func3 at 0x000001FFAF8C4950>, 
     'func4': <function MyClass.func4 at 0x000001FFAF8C49D8>, 
     '__len__': <function MyClass.__len__ at 0x000001FFAF8C4A60>,
     '__dict__': <attribute '__dict__' of 'MyClass' objects>, 
     '__weakref__': <attribute '__weakref__' of 'MyClass' objects>, 
     '__doc__': None
    }
    
    """    

    5.与类相关的魔术属性

    # ### 与类相关的魔术属性
    
    class Man():
        pass
        
    class Woman():
        pass
    
    class Children(Man,Woman):
        '''
        成员属性:eye
        成员方法:skylight moonread __makebaby
        完成的功能:描述小孩天生神力
        '''
        eye = "血轮眼"
        
        def skyligth(self):
            print("一下生,直接使用天照,让世界变得混乱")
        
        def moonread(self,func):
            print("一下生,使出了武功绝学,月读,世界都黑暗里~")
            print(func.__name__,type(func.__name__)) #earth_boom
            
        def __makebaby(self):
            print("这一手招数,只能我自己用")
    obj = Children()
    
    
    # __dict__ 获取对象或类的内部成员结构
    print(obj.__dict__)
    print(Children.__dict__)
    '''
    {}
    {'__module__': '__main__', '__doc__': '
        成员属性:eye
        成员方法:skylight moonread __makebaby
        完成的功能:描述小孩天生神力
        ', 'eye': '血轮眼', 'skylight': <function Children.skylight at 0x0000000002985620>, 'moonread': <function Children.moonread at 0x00000000029856A8>, '_Children__makebaby': <function Children.__makebaby at 0x0000000002985730>}
    
    '''
    # __name__ 获取类名函数名
    def eatrh_boom():
        print("使用一招地爆天星")
    obj.moonread(earth_boom)
    obj.moonread(Children)
    '''
    一下生,使出了武功绝学,月读,世界都黑暗里~
    earth_boom <class 'str'>
    一下生,使出了武功绝学,月读,世界都黑暗里~
    Children <class 'str'>
    '''
    
    # __class__ 获取当前对象所属的类
    print(obj.__class)
    
    #__bases__获取一个类直接继承的所有父类 返回元组
    print(Children.__bases__)  # (<class '__main__.Man'>, <class '__main__.Woman'>)

     总结:

    今天主要讲了几类魔术方法以及与类相关的魔术属性
    首先讲了__del__魔术方法,又称析构方法
    触发时机,当对象被内存回收的时候自动触发
    (1.页面执行完毕回收所有变量2.所有对象被del的时候)
    参数:一个self接收对象
    返回值:无
    
    __str__和__repr__
    __str__魔术方法触发时机使用print打印对象或者str对象的时候触发
    参数:一个self接收当前对象
    返回值:必须返回字符串类型
    
    __repr__魔术方法
    触发时机使用repr对象的时候触发
    功能与str魔术方法相似
    参数:一个self接收对象
    返回值必须返回字符串类型
    要注意的时候,在系统底层如果定义了repr,将会默认赋值给str方法
    即 __str__ = __repr__
    #也就是如果先用的repr方法,那么可以也用直接打印或者str转
    但是如果先用的str方法,那么就不能用repr方法转
    
    call魔术方法触发时机把对象当做函数调用的时候自动触发
    功能模拟函数化操作
    参数不固定至少一个self参数
    返回值看需求
    
    bool魔术方法
    触发时机:使用bool(对象)的时候自动输出
    功能:强转对象
    参数:一个self接收当前对象
    返回值:必须是布尔类型
    
    
    add魔术方法 与之相反的__radd__反向加法
    触发时机:使用对象进行运算相加的时候自动触发
    功能:对象运算
    参数:二个对象参数
    返回值:运算后的值
    #对象在加号+左侧的时候,自动触发add魔术方法
    对象在右侧时,自动触发__radd__魔术方法  
    
    __len__ 魔术方法
    触发时机:使用len(对象)的时候自动触发
    功能:用于检测对象中或者类中成员的个数
    参数:一个self接收当前对象
    返回值:必须返回整型
    
    与类相关的魔术属性
    __name__ 获取类名函数名
    __dict__ 获取对象或类的内部成员结构
    __class__ 获取当前对象所属的类
    __bases__获取一个类直接继承的所有父类 返回元组
  • 相关阅读:
    LR回放webservice脚本报错------------mmdrv.exe应用程序错误(未解决)
    转载:shell中#*,##*,#*,##*,% *,%% *的含义及用法
    转载:Linux命令经典面试题:统计文件中出现次数最多的前10个单词
    Python---求100以内的质数
    用shell编写小九九乘法表程序
    python中遇到的问题:IndentationError: unexpected indent
    关于redis的持久化策略
    关于equals和hashcode问题
    Spring源码窥探之:Spring AOP初步使用
    Spring源码窥探之:@Value
  • 原文地址:https://www.cnblogs.com/weiweivip666/p/13020877.html
Copyright © 2020-2023  润新知