day25:7个魔术方法&5个关于类的魔术属性
目录1.__del__(析构方法) 2.魔术方法:__str__ 3.魔术方法:__repr__ 4.魔术方法:__call__ 5.魔术方法:__bool__ 6.魔术方法:__add__&__radd__ 7.魔术方法:__len__ 8.与类相关的魔术属性 一个小表格方便记忆哈__del__ (析构方法)__del__简要介绍1.触发时机:当对象被内存回收的时候自动触发 (1)页面执行完毕回收所有变量 (2)所有对象被del的时候 2.功能:对象使用完毕后资源回收 3.参数:一个self接受对象 4.返回值:无 第一种情况:页面执行完毕回收所有变量class LangDog(): food = "改吃蔬菜" def __init__(self,name): self.name = name __del__(self): print(析构方法被触发") 0001=====) obj = LangDog(肉丝0002=====# 1.页面执行完毕回收所有变量 print(obj.name) 当执行完这句话后,才算页面执行完毕,这个时候触发__del__析构方法 ''' 运行结果: ===== ===== 肉丝 析构方法被触发 ''' 第二种情况:所有对象被del的时候如何理解第二种情况中所说到的所有对象? 代码如下: ) obj1 = LangDog() obj2 = obj1 <=====start=====>del<=====end=====>") 打印结果: 虽然obj1对象被删除了,但是obj2对象并没有被删除,所以不会触发析构方法 打印了“析构方法被触发”是因为整个页面执行完毕了,也会触发析构方法 使用__del__模拟文件操作3.模拟文件操作 import os ReadFile(): __new__(cls,filename): if os.path.exists(filename): 判断文件路径是否存在 return object.__new__(cls) 如果文件存在,创建文件对象 else: return 该文件是不存在的") 如果文件不存在,给予错误提示 打开文件 self.fp = open(filename,mode=r+",encoding=utf-8) def readcontent(self): 读取文件 return self.fp.read() 关闭文件 self.fp.close() obj = ReadFile(1.txt) if obj is not None: res = obj.readcontent() print(res) : 没有该类文件) 当然,也可以用三元运算符来实现 """ 真值 if 条件表达式 else 假值 """ print(obj.readcontent()) not None else ") 魔术方法:__str____str__简要介绍1.触发时机: 使用print(对象)或者str(对象)的时候触发 2.功能: 查看对象 3.参数: 一个self接受当前对象 4.返回值: 必须返回字符串类型 Cat(): gift = 小猫咪会卖萌求猫粮,小猫咪抓老鼠" name __str__ self.cat_info() cat_info(self): return 小猫咪的名字是{},小猫咪{}元".format(self.name,5000) __repr__ = __str__ tom = Cat(汤姆 方法一. print(对象) (tom) 方法二. str(对象) res = str(tom) print(res) 魔术方法:__repr__1.触发时机: 使用repr(对象)的时候触发 2.功能: 查看对象,与魔术方法__str__相似 3.参数: 一个self接受当前对象 4.返回值: 必须返回 Mouse(): gift = 偷粮食__repr__ self.mouse_info() mouse_info(self): 名字是{},龙生龙,凤生凤,老鼠的儿子会打洞,还会{}.format(self.name,self.gift) 系统在底层,自动加了一句赋值操作 __str__ = jerry = Mouse(杰瑞) res = repr(jerry) (res) 因为系统底层赋值的原因,在打印对象或者强转对象为字符串的时候,仍然可以触发; (jerry) res = str(jerry) print(res) 魔术方法:__call__1.触发时机:把对象当作函数调用的时候自动触发 2.功能: 模拟函数化操作 3.参数: 参数不固定,至少一个self参数 4.返回值: 看需求 基本用法(1) 基本用法 MyClass(): a = 1 __call__call魔术方法被触发了) obj = MyClass() 实例化一个对象 obj() 把对象当做函数调用,此时会触发__call__方法 模拟洗衣服的过程(2) 模拟洗衣服的过程 Wash(): 我现在要洗{}.format(something)) self.step1() self.step2() self.step3() 洗完了 step1(self): 加热水,家洗衣粉,加洗衣液,加洗涤剂) step2(self): 衣服泡进去搅乱 打散 搓一搓~ step3(self): 脱水,穿上) obj = Wash() 方法一 # obj.step1() obj.step2() obj.step3() 方法二 res = obj(衣服 把对象obj当做函数进行调用,此时触发__call__方法,执行__call__方法所有内容 print(res) 模拟内置的int方法,实现相应的操作(有时间再分析)(3) 模拟内置int 实现相应的操作 math MyInt(): def calc(self,num,sign=1): print(num,sign) 去掉左边多余的0 strvar = num.lstrip(0) print(strvar) 为了防止都是0,如果去掉之后为空,返回0 if strvar == "" 0 正常情况下,执行存数字字符串变成数字,在乘上相应的符号,得出最后的结果 return eval(strvar) * sign if isinstance(num,bool): if num == True: return 1 elif num == False: 0 elif num 方法一 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 math.ceil(num) if (num[0] == +" or num[0]== -and num[1:].isdecimal(): if num[0] == : sign = 1 : sign = -1 return self.calc(num[1:],sign) num.isdecimal(): self.calc(num) : 老铁,这个真转不了 myint = MyInt() myint(5) => 5 myint(3.14) => 3 res = myint(True) (res) res = myint(100(res) res = myint(3333.14print(res,type(res)) 3 bool int float "12312312323" int(3.14) => 3 print(int(3.14)) 3 print(int(-3.14)) -3 <===>print(myint(3.14)) print(myint(-0.2)) print(int(000000000000000000000000000000000000000000123000000000000000000000000000000000000000000000000"),1111222333+000000000000000000000000000000000000000000123-000000000000000000000000000000000000000000123000000000000000000000000000000000000000000123<==111=>print(myint(+0000000002344568992003.143434print(myint(+-++-+-+-+-+-+-+-+-+-+-++++++++-----234234),1)"><====>print(int(+-++-+-+-+-+-+-+-+-+-+-++++++++-----234234),1)">) 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__简要介绍1.触发时机:使用bool(对象)的时候自动触发 2.功能:强转对象 3.参数:一个self接受当前对象 4.返回值:必须是布尔类型 MyClass(): __bool__ False obj = MyClass() res = bool(obj) print(res) 类似的还有如下等等(了解): __complex__(self) 被complex强转对象时调用 __int__(self) 被int强转对象时调用 __float__(self) 被float强转对象时调用 ... ... 魔术方法:__add__,__radd____add__简要介绍1.触发时机:使用对象进行运算相加的时候自动触发 2.功能:对象运算 3.参数:二个对象参数 4.返回值:运算后的值 5.注意点: 对象在加号+的左侧时,自动触发__add__方法 对象在加号+的右侧时,1)">__radd__方法 加号左侧和右侧都是对象时,先触发__add__方法,再触发__radd__方法 MyClass1(): num 对象在加号+的左侧时,自动触发 __add__ print(self) print(other) return self.num + other return 10 + 7 = 17 对象在加号+的右侧时,1)">__radd__return self.num * 2 + other 第一种 a = MyClass1(10) res = a + 7 (res) 第二种 b = MyClass1(5) res = 20 + b 第三种 <============>) res = a+b (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 """ 类似的还有如下等等(了解): __sub__(self,other) 定义减法的行为:- __mul__(self,other) 定义乘法的行为:* __truediv__(self,other) 定义真除法的行为:/ 魔术方法:__len____len__简要介绍1.触发时机:使用len(对象)的时候自动触发 2.功能:用于检测对象中或者类中成员的个数 3.参数:一个self接受当前对象 4.返回值:必须返回整型 MyClass(): pty1 = 1 pty2 = 2 __pty3 = 3 pyt3 =10 pty100 = 90 func1(): pass __func2(): __func3pass __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) 将符合条件的成员添加到列表中 len(lst) 方法二 lst = [i in dic if ))] return len(lst) 与类相关的魔术属性__dict__ 获取对象或类的内部成员结构 __doc__ 获取对象或类的内部文档 __name__ 获取类名函数名 __class__ 获取当前对象所属的类 __bases__ 获取一个类直接继承的所有父类,返回元组 Man(): pass Woman(): Children(Man,Woman): 功能: 描述小孩天生的属性 成员属性:eye,skin 成员方法:skylight,moonread,__makebaby """ eye = 万花筒血轮眼 skin = 白色" skylight(self): 宇智波家族的小孩,天生能够发动天照技能 moonread(self,func): func = func111 ) res = func.__name__ (res,type(res)) __makebaby这一手招数,只能我自己用) __dict__ 获取对象或类的内部成员结构 obj = Children() print(obj.__dict__print(Children. __doc__ 获取对象或类的内部文档 __doc__ __name__ 获取类名函数名 func111(): 我是func111方法 获取函数名 obj.moonread(func111) 获取类名 obj.moonread(Man) __class__ 获取当前对象所属的类 __class__ __bases__ 获取一个类直接继承的所有父类,返回元组 __bases__) ? (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |