一、__del__ 魔术方法(析构方法)
''' 触发时机:当对象被内存回收的时候自动触发[1.页面执行完毕回收所有变量 2.关于当前对象的所有对象被del的时候] 功能:对象使用完毕后资源回收 参数:一个self接受对象 返回值:无 '''
1、页面执行完毕回收所有变量
class LangDog(): food = "改吃蔬菜" def __init__(self,name): self.name = name def __del__(self): print("析构方法被触发") obj = LangDog("肉丝") print(obj.name)
2、所有对象被del的时候没有对象指向内存空间地址
class LangDog(): food = "改吃蔬菜" def __init__(self,name): self.name = name def __del__(self): print("析构方法被触发") obj = LangDog("肉丝") other_obj = obj print("<=====start=====>") del obj del other_obj print("<=====end=====>")
3、模拟文件操作
import os class ReadFile(): def __new__(cls,filename): if os.path.exists(filename): return object.__new__(cls) else: return print("该文件是不存在的") def __init__(self,filename): # 打开文件 self.fp = open(filename,mode="r+",encoding="utf-8") def readcontent(self): # 读取文件 return self.fp.read() def __del__(self): # 关闭文件 self.fp.close() obj = ReadFile("属性_反射.md") """ if obj is not None: res = obj.readcontent() print(res) else: print("没有该类文件") """ # 三运运算符 """ 真值 if 条件表达式 else 假值 """ print(obj.readcontent()) if obj is not None else print("没有该类文件")
二、__str__ 和 __repr__
1、__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,5000) # __repr__ = __str__ tom = Cat("汤姆") # 方法一. print(对象) # print(tom) # 方法二. str(对象) res = str(tom) print(res) # 小扩展 让repr强转对象时,触发打印内容 res = repr(tom) print(res)
手动添加__repr__ = __str__ 把 str 赋值给 str 可以使用 repr()
2、__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) # 系统在底层,自动加了一句赋值操作 __str__ = __repr__ jerry = Mouse("杰瑞") res = repr(jerry) print(res) # 因为系统底层赋值的原因,在打印对象或者强转对象为字符串的时候,仍然可以触发; print(jerry) res = str(jerry) print(res)
三、__call__
''' 触发时机:把对象当作函数调用的时候自动触发 功能: 模拟函数化操作 参数: 参数不固定,至少一个self参数 返回值: 看需求 '''
1、基本使用
class MyClass(): a = 1 def __call__(self): print("call魔术方法被触发了") obj = MyClass() obj()
2、模拟洗衣服的过程
class Wash(): def __call__(self,something): print("我现在要洗{}".format(something)) self.step1() self.step2() self.step3() return "洗完了" def step1(self): print("加热水,家洗衣粉,加洗衣液,加洗涤剂") def step2(self): print("衣服泡进去搅乱 打散 搓一搓~ ") def step3(self): print("脱水,穿上") obj = Wash() # 方法一 # obj.step1() # obj.step2() # obj.step3() # 方法二 res = obj("衣服") print(res)
3、模拟内置int 实现相应的操作
import math class MyInt(): def calc(self,num,sign=1): # print(num,sign) # 去掉左边多余的0 strvar = num.lstrip("0") # print(strvar) # 为了防止都是0 ,如果去掉之后为空,返回0 if strvar == "": return 0 # 正常情况下,执行存数字字符串变成数字 , 在乘上相应的符号,得出最后的结果 return eval(strvar) * sign def __call__(self,num): if isinstance(num , bool): if num == True: return 1 elif num == False: return 0 elif isinstance(num,int): return num elif isinstance(num,float): # 方法一 """ strvar = str(num) lst = strvar.split(".") return eval(lst[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.calc(num[1:],sign) elif num.isdecimal(): return self.calc(num) else: return "老铁,这个真转不了" myint = MyInt() # myint(5) => 5 # myint(3.14) => 3 res = myint(True) print(res) res = myint(100) print(res) res = myint(3333.14) print(res, type(res)) # 3 # bool int float "12312312323" # int(3.14) => 3 print(int(3.14)) # 3 print(int(-3.14)) # -3 print("<===>") print(myint(3.14)) print(myint(-0.2)) print("<===>") print(int("0000000000000000000000000000000000000000001230000000")) print(int("00000000000000000000000000000000000000000"),"1111222333") print(int("+000000000000000000000000000000000000000000123")) print(int("-000000000000000000000000000000000000000000123")) print(int("000000000000000000000000000000000000000000123")) print("<==111=>") print(myint("+000000000234")) print(myint("000000000000000000000000000000000000000000123")) print(myint("456899200")) print(myint("3.143434")) print(myint(+-++-+-+-+-+-+-+-+-+-+-++++++++-----234234),"<====>") print(int(+-++-+-+-+-+-+-+-+-+-+-++++++++-----234234),"<====>") """ exec("a = 3") print(a) eval("4") """ # print(math.floor(0.14)) # 0 # print(math.floor(3.14)) # 3 # print(math.ceil(-3.14)) # -3
四、__bool__ 魔术方法
''' 触发时机:使用bool(对象)的时候自动触发 功能:强转对象 参数:一个self接受当前对象 返回值:必须是布尔类型 ''' """ 类似的还有如下等等(了解): __complex__(self) 被complex强转对象时调用 __int__(self) 被int强转对象时调用 __float__(self) 被float强转对象时调用 ... ... """
class MyClass(): def __bool__(self): return False obj = MyClass() res = bool(obj) print(res)
五、__add__ 魔术方法 (与之相关的__radd__ 反向加法)
''' 触发时机:使用对象进行运算相加的时候自动触发 功能:对象运算 参数:二个对象参数 返回值:运算后的值 ''' ''' 类似的还有如下等等(了解): __sub__(self, other) 定义减法的行为:- __mul__(self, other) 定义乘法的行为: __truediv__(self, other) 定义真除法的行为:/ ... ... '''
class MyClass1(): def __init__(self,num): self.num = num # 对象在加号+的左侧时,自动触发 def __add__(self,other): # print(self) # print(other) return self.num + other # return 10 + 7 = 17 # 对象在加号+的右侧时,自动触发 def __radd__(self,other): # print(self) # print(other) return self.num * 2 + other # 第一种 a = MyClass1(10) res = a + 7 print(res) # 第二种 b = MyClass1(5) res = 20 + b print(res) # 第三种 print("<============>") res = a+b print(res) """ 第一次触发魔术方法, a+ =>触发__add__方法 self => a other => b self.num + other => a.num+ b => 10 + b res = 10 + b 第二次触发魔术方法 __radd__ self => b other=> 10 self.num * 2 + other => b.num*2 + other => 5 * 2 + 10 => 20 res = 20 """
六、__len__ 魔术方法
''' 触发时机:使用len(对象)的时候自动触发 功能:用于检测对象中或者类中成员的个数 参数:一个self接受当前对象 返回值:必须返回整型 ''' ''' 类似的还有如下等等(了解): __iter__(self) 定义迭代容器中的元素的行为 __reversed__(self) 定义当被 reversed() 调用时的行为 __contains__(self, item) 定义当使用成员测试运算符(in 或 not in)时的行为 ... ... '''
# len(obj) => 返回类中自定义成员的个数 class MyClass(): pty1 = 1 pty2 = 2 __pty3 = 3 pyt3 =10 pty100 = 90 def func1(): pass def __func2(): pass def __func3(): pass def __len__(self): lst = [] dic = MyClass.__dict__ # 方法一 """ # print(MyClass.__dict__) # print(object.__dict__) dic = MyClass.__dict__ for i in dic: if not(i.startswith("__") and i.endswith("__")): lst.append(i) return len(lst) """ # 方法二 lst = [i for i in dic 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 0x7fc198171378>, 'func2': <function MyClass.func2 at 0x7fc198171400>, '_MyClass__func3': <function MyClass.__func3 at 0x7fc198171488>, '__len__': <function MyClass.__len__ at 0x7fc198171510>, '__dict__': <attribute '__dict__' of 'MyClass' objects>, '__weakref__': <attribute '__weakref__' of 'MyClass' objects>, '__doc__': None } """
七、与类相关的魔术属性
class Man(): pass class Woman(): pass class Children(Man,Woman): """ 功能: 描述小孩天生的属性 成员属性:eye , skin 成员方法:skylight , moonread , __makebaby """ eye = "万花筒血轮眼" skin = "白色" def skylight(self): print("宇智波家族的小孩,天生能够发动天照技能") def moonread(self,func): # func = func111 print("宇智波家族的小孩,能够发动月亮的光照消灭你~") res = func.__name__ print(res,type(res)) def __makebaby(self): print("这一手招数,只能我自己用")
1、__dict__ 获取对象或类的内部成员结构
obj = Children() print(obj.__dict__) print(Children.__dict__)
2、__doc__ 获取对象或类的内部文档
print(obj.__doc__) print(Children.__doc__)
3、__name__ 获取类名函数名
def func111(): print("我是func111方法") # 获取函数名 obj.moonread(func111) # 获取类名 obj.moonread(Man)
4、__class__ 获取当前对象所属的类
print(obj.__class__)
5、__bases__ 获取一个类直接继承的所有父类,返回元组
print(Children.__bases__)