zoukankan      html  css  js  c++  java
  • 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__获取一个类直接继承的所有父类 返回元组
  • 相关阅读:
    【面积并】 Atlantis
    【动态前k大 贪心】 Gone Fishing
    【复杂枚举】 library
    【双端队列bfs 网格图建图】拯救大兵瑞恩
    【奇偶传递关系 边带权】 奇偶游戏
    【权值并查集】 supermarket
    CF w4d3 A. Pythagorean Theorem II
    CF w4d2 C. Purification
    CF w4d2 B. Road Construction
    CF w4d2 A. Cakeminator
  • 原文地址:https://www.cnblogs.com/weiweivip666/p/13020877.html
Copyright © 2011-2022 走看看