__new__
# ### __new__ 魔术方法 ''' 触发时机:实例化类生成对象的时候触发(触发时机在__init__之前) 功能:控制对象的创建过程 参数:至少一个cls接受当前的类,其他根据情况决定 返回值:通常返回对象或None ''' class MyClass2(): b = 2 obj2 = MyClass2() # (1) 基本语法 """ 借助object父类中的__new__魔术方法,创建对象 需要传递cls这个参数,代表的是本类,为本类创建对象,进行返回 """ class MyClass(): a = 1 def __new__(cls): print(cls) # <class '__main__.MyClass'> # 借助父类object,里面的__new__魔术方法创建对象 # 1.返回本对象 return object.__new__(cls) # 2.返回其他类的对象 # return obj2 # 3.不返回任何对象 # return None obj = MyClass() print(obj) # 返回本对象 # print(obj.a) # 返回其他类对象 # print(obj.b) # (2) 验证__new__和__init__两个方法的触发时间 """ __new__ 用来创建对象 __init__ 用来初始化对象的 先创建在初始化 __new__ 触发时机快于__init__ """ class MyClass(): def __new__(cls): print(1) return object.__new__(cls) def __init__(self): print(2) obj = MyClass() # 传一个参数的情况 class MyClass(): def __new__(cls,name): return object.__new__(cls) def __init__(self,name): self.name = name obj = MyClass("Max") # 传多个参数的情况 class MyClass(): # 多个参数下,用收集参数来保证形参实参一一对应 def __new__(cls,*args,**kwargs): return object.__new__(cls) def __init__(self,name,skin,age): self.name = name self.skin = skin self.age = age obj = MyClass("Max","绿色",108) print(obj.name) # 注意点: """ 如果__new__返回的不是自己本类的对象,不会触发构造方法__init__ """ class MyClass(): def __new__(cls,*args,**kwargs): print("__new__被触发") return obj2 def __init__(self): print("__init__构造方法被触发") obj = MyClass()
__单例
# ### 单态模式 : 无论实例化对象多少次,都有且只有一个对象 # (1) 基本语法 """为了节省空间,加快效率,提出单态模式""" class Singleton(): __obj = None def __new__(cls): if cls.__obj is None: cls.__obj = object.__new__(cls) return cls.__obj """ 第一次实例化的时候,cls.__obj is None 返回True 执行object.__new__(cls) 返回对象 让cls.__obj接受对象 return 该对象 第二次实例化的时候,cls.__obj is None 返回False return cls.__obj 内存中堆空间存放的对象返回 第三次实例化的时候,cls.__obj is None 返回False return cls.__obj 内存中堆空间存放的对象返回 以后 .. 每次进行实例化的对象,都是第一次存储的那个对象 就实现了无论实例化几次,都返回同一个对象; """ obj1 = Singleton() obj2 = Singleton() obj3 = Singleton() print(obj1,obj2,obj3) print(obj1 is obj2) # (2) 单态模式 + 构造方法 class Singleton(): __obj = None def __new__(cls,*args,**kwargs): if cls.__obj is None: cls.__obj = object.__new__(cls) return cls.__obj def __init__(self,name): self.name = name obj1 = Singleton("Tom") obj2 = Singleton("Max") print(obj1.name) print(obj2.name) """ 第一次实例化的时候, self.name = 李诗韵 第一次实例化的时候, 返回的是第一次实例化出来的对象 将该对象以前的name属性 从李诗韵改成黄乐西 self.name = 黄乐西 打印 obj1.name obj2.name 都是黄乐西 """
__del__
# ### 魔术方法 __del__ (析构方法) '0'' 触发时机:当对象被内存回收的时候自动触发[1.页面执行完毕回收所有变量 2.所有对象被del的时候] 功能:对象使用完毕后资源回收 参数:一个self接受对象 返回值:print(无2..) .. ...... ''' # (1) 基本使用 class Dog(): def __init__(self,name): self.name = name def eatmeat(self): print("小狗喜欢吃肉包子") def __del__(self): print("析构方法被触发") # (1)页面执行完毕回收所有变量 obj = Dog("詹姆斯·蛋蛋") obj.eatmeat() # (2)所有对象被del的时候 """ 两个变量指向同一个对象,其中删除obj这个变量的指向关系, 还有一个变量在指向该对象,所以对象没有被删除,不能够触发析构方法__del__ """ obj2 = obj print("===start===") del obj # del obj2 print("===end====") # (3)读取文件操作 import os """ fp = open("文件名",mode="r",encoding="utf-8") res = fp.read() fp.close() """ 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 readfile(self): res = self.fp.read() return res # 关闭文件 def __del__(self): self.fp.close() obj = ReadFile("ceshi.txt") res = obj.readfile() print(res)
__call__
# ###__call__ 魔术方法 ''' 触发时机:把对象当作函数调用的时候自动触发 功能: 模拟函数化操作 参数: 参数不固定,至少一个self参数 返回值: 看需求 ''' # (1) 基本语法 class MyClass(): def __call__(self): print("call方法被触发") obj = MyClass() obj() # (2) 可以使用__call__统一调用方法,[模拟洗衣服的过程] 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() """ # 方法二 # obj() res = obj("洗衣服") print(res) # 模拟int方法,自定义类 import math """bool int float 字符串""" class MyInt(): def myfunc(self,num,sign=1): # print(num) # print(sign) res = num.lstrip("0") if res == "": return 0 return eval(res) * sign def __call__(self,n): # 判断是不是bool if isinstance(n,bool): if n == True: return 1 else: return 0 # 判断是不是int elif isinstance(n,int): return n # 判断是不是float elif isinstance(n,float): if n > 0: return math.floor(n) else: return math.ceil(n) # 判断是不是字符串 elif isinstance(n,str): # 判断是否带符号 + - if (n[0] == "+" or n[0] == "-") and n[1:].isdecimal(): sign = None # 获取符号 if n[0] == "+": sign = 1 elif n[0] == "-": sign = -1 return self.myfunc(n[1:],sign) # 判断是否是纯数字字符串 elif n.isdecimal(): return self.myfunc(n) else: return "老弟,这个东西算不了." else: return "脑弟,这个算不了" myint = MyInt() res = myint(True) res = myint(-19.89) # res = myint("-abcddfdf") # res = myint([1,2,3]) print(res,type(res))
__str__
__repr__
# ### __str__ 魔术方法 ''' 触发时机: 使用print(对象)或者str(对象)的时候触发 功能: 查看对象 参数: 一个self接受当前对象 返回值: 必须返回字符串类型 ''' class Cat(): gift = "卖萌,喵喵喵" def __init__(self,name): self.name = name def cat_info(self): return "小猫的名字{},小猫的天赋{}".format(self.name,self.gift) def __str__(self): return self.cat_info() tom = Cat("汤姆") # 方法一 print(tom) # 方法二 res = str(tom) print(res) # ### __repr__ 魔术方法 ''' 触发时机: 使用repr(对象)的时候触发 功能: 查看对象,与魔术方法__str__相似 参数: 一个self接受当前对象 返回值: 必须返回字符串类型 ''' class Mouse(): gift = "偷油吃,下不来" def __init__(self,name): self.name = name def mouse_info(self): return "小老鼠名字{},天赋{}".format(self.name,self.gift) def __repr__(self): return self.mouse_info() # 在系统底层默认加了如下一句话 # __str__ = __repr__ jerry = Mouse("杰瑞") res = repr(jerry) print(res) print(jerry) res = str(jerry) print(res)
__bool__
__add__
__radd__
__len__
0# ### __bool__ 魔术方法 ''' 触发时机:使用bool(对象)的时候自动触发 功能:强转对象 参数:一个self接受当前对象 返回值:必须是布尔类型 ''' class MyClass(): def __bool__(self): return False obj = MyClass() res = bool(obj) print(res) #__add__ 魔术方法 (与之相关的__radd__ 反向加法) ''' 触发时机:使用对象进行运算相加的时候自动触发 功能:对象运算 参数:二个对象参数 返回值:运算后的值 ''' class MyClass(): def __init__(self,num): self.num = num """对象在 加号+ 的左侧时,自动触发""" def __add__(self,other): print("add方法被触发") """ self 接受的是obj对象 other 接受的是数字 """ # print(self) # print(other) return self.num + other """对象在 加号+ 的右侧时,自动触发""" def __radd__(self,other): """ self 接受的是对象b other 接受的是3 """ return self.num + other * 3 # 5 + 3 * 3 = 14 # (1) add 方法 a = MyClass(10) res = a + 1 print(res) # (2) radd方法 b = MyClass(5) res = 3 + b print(res) # (3) 对象 + 对象 """ 先触发add方法 self 接受a other 接受b return self.num + other => return 10 + b res = 10 + b 后触发radd方法 self 接受b other 接受10 return self.num + other * 3 => 5 + 10 *3 = 35 """ res = a+b print(res) #__len__ 魔术方法 ''' 触发时机:使用len(对象)的时候自动触发 功能:用于检测对象中或者类中成员个数 参数:一个self接受当前对象 返回值:必须返回整型 ''' class MyClass(): pty1 = 1 pty2 = 2 __pty3 = 3 def func1(): print(1) def func2(): pass def __func3(): pass def __len__(self): dic = MyClass.__dict__ print(dic) """ { '__module__': '__main__', 'pty1': 1, 'pty2': 2, '_MyClass__pty3': 3, 'func1': <function MyClass.func1 at 0x7f99d664f6a8>, 'func2': <function MyClass.func2 at 0x7f99d664f730>, '_MyClass__func3': <function MyClass.__func3 at 0x7f99d664f7b8>, '__len__': <function MyClass.__len__ at 0x7f99d664f840>, '__dict__': <attribute '__dict__' of 'MyClass' objects>, '__weakref__': <attribute '__weakref__' of 'MyClass' objects>, '__doc__': None } """ # 方法一 """ lst = [] for i in dic: if not( i.startswith("__") and i.endswith("__") ): lst.append(i) print(lst) """ # 方法二 lst = [ i for i in dic if not( i.startswith("__") and i.endswith("__") )] return len(lst) obj = MyClass() res = len(obj) print(res)