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__获取一个类直接继承的所有父类 返回元组
原文地址:https://www.cnblogs.com/weiweivip666/p/13020877.html