Python-魔术⽅法
⼀、__new__⽅法
触发时机:实例化类⽣成对象的时候触发(触发时机在__init__之前)
功能:控制对象的创建过程
参数:⾄少⼀个cls接受当前的类,其他根据情况决定
返回值:通常返回对象或None
1.基本语法
class MyClass():
a = 1
obj = MyClass()
print(obj)
class MyClass1(object):
def __new__(cls):
print(cls)
# (1)借助⽗类object 类.⽅法(),返回本类⾃⼰的对象
# obj = object.__new__(cls)
# return obj
# (2)返回其他类的对象
# return obj
# (3)不返回任何对象
return None
obj = MyClass1()
print(obj)
new ⽤来创建对象 init ⽤来初始化对象(前提的有对象) 先创建对象,再去初始化对象,所以new快于init class Boat():
def __init__(self):
print(2)
def __new__(cls):
print(1)
return object.__new__(cls)
obj = Boat()
# ⼀个参数
class Boat():
def __new__(cls,name):
return object.__new__(cls)
def __init__(self,name):
self.name = name
obj = Boat("泰坦尼克号")
print(obj.name)
# 多个参数
class Boat():
def __new__(cls,*args,**kwargs):
return object.__new__(cls)
def __init__(self,name,a,b,c,d,e):
self.name = name
obj = Boat("泰坦尼克号",2,3,4,5,6)
print(obj.name)
4.如果返回的不是本类的对象,不会触发__init__构造⽅法
print("<=====>")
class MyClass():
a = 1
other_obj = MyClass()
class Boat():
return other_obj
def __init__(self):
print("构造⽅法被触发~")
obj = Boat()
⼆、单例(态)模式
⽬的意义:
为了节省内存空间,仅仅是为了调⽤类中的成员,
不需要额外给该对象添加任何成员,这个场景,使⽤单态.
⽐如:操作数据库的增删改查这样的类,是不需要的.
1.基本语法
class Singleton():
__obj = None
def __new__(cls):
if cls.__obj is None:
cls.__obj = object.__new__(cls)
return cls.__obj
"""
<__main__.Singleton object at 0x000001FB3F207278>
有这个对象直接返回,没这个对象,就给你创建,保证只有⼀个
第⼀次实例化时,if cls.__obj is None 条件为真 , 创建⼀个对象放到cls.__obj , 最后返回
第⼆次实例化时,if cls.__obj is None 条件为假 , 直接返回
第三次实例化时,if cls.__obj is None 条件为假 , 直接返回
第三次实例化时,if cls.__obj is None 条件为假 , 直接返回
"""
obj1 = Singleton()
print(obj1)
obj2 = Singleton()
print(obj2)
obj3 = Singleton()
print(obj3)
obj4 = Singleton()
print(obj4)
# 打印结果为同⼀个对象
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("aaa")
obj2 = Singleton("bbb")
# 求答案
print(obj1.name)
print(obj2.name)
# obj1 和 obj2 都是同时指向同⼀个对象,因为对象只创建了⼀个对象.name 是获取他后边bbb那个值,是同⼀个值打印了2次;
三、__del__析构⽅法
触发时机:当对象被内存回收的时候⾃动触发[1.页⾯执⾏完毕回收所有变量 2.所有对象被del的时候]功能:对象使⽤完毕后资源回收
参数:⼀个self接受对象
返回值:⽆
1.基本⽅法
del只会触发⼀次,即如果先把所有的对象给删除了,那么在执⾏完所有代码之后不会再触发
class LangDog():
food = "吃⾁"
def __init__(self,name):
self.name = name
print("析构⽅法被触发..")
#(1) 页⾯执⾏完毕回收所有变量
obj = LangDog("⼑疤")
print(obj.name)
#(2) 所有对象被del的时候
"""
当⼀个值,没有任何变量指向或者说引⽤,这个值才会被真正的释放
"""
other_obj = obj
print(other_obj is obj)
print("<==start==>")
del obj
del other_obj
print("<==end==>")
2.模拟⽂件操作练习
将⽂件操作也封装起来,这要其他同事在使⽤⽂件操作时候,只需要调⽤我们写的代码就可以了,减少了代码冗余import os
class ReadFile():
def __new__(cls,filename):
# 判断⽂件是否存在
if ists(filename):
return object.__new__(cls)
else:
return print("该⽂件是不存在的")
def __init__(self,filename):
# 打开⽂件操作
self.fp = open(filename,mode="r",encoding="utf-8")
def readcontent(self):
# 读取⽂件操作
content = ad()
return content
def __del__(self):
self.fp.close()
obj = ReadFile("")
res = adcontent()
print(res)
四、__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,self.gift)
tom = Cat("汤姆")
# 触发⽅式⼀, print 打印该对象
print(tom)
# 触发⽅式⼆, str
res = str(tom)
print(res)
2.__repr__
触发时机: 使⽤repr(对象)的时候触发
功能: 查看对象,与魔术⽅法__str__相似
参数: ⼀个self接受当前对象
返回值: 必须返回字符串类型
class Mouse():
gift = "打洞"
def __init__(self,name):
self.name = name
def __repr__(self):
use_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(res)
五、__call__⽅法
触发时机:把对象当做函数调⽤时候⾃动触发
功能:模拟函数化操作
参数:参数不固定,⾄少⼀个self参数
返回值:看需求
1.基本⽤法
class MyClass():
a = 1
""""""
def __call__(self):
print("call魔术⽅法被触发..")
obj = MyClass()
obj()
2.call魔术⽅法的应⽤
# 模拟洗⾐服的过程
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("裤衩")
obj("⾐服")
obj("袜⼦")
obj("⽑⼱")
# 如不使⽤魔术⽅法,我们每次洗⾐服都需要调三个函数
obj.step1("裤衩")
obj.step2()
obj.step1("⾐服")
obj.step2()
obj.step3()
obj.step1("袜⼦")
obj.step2()
obj.step3()
obj.step1("⽑⼱")
obj.step2()
obj.step3()
3.模拟内置函数int
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:
il(num)
"""
return math.floor(num) if num >= 0 il(num)
elif isinstance(num,str):
# ⾸字符是+或者- 后边的是纯数字字符串
if (num[0] == "+" or num[0] == "-") and num[1:].isdecimal(): if num[0] == "+":
sign = 1
else:
sign = -1
alc(num[1:],sign)
elif num.isdecimal():
alc(num)
else:
return "⽼铁,这个真不能转~"
六、__bool__⽅法
触发时机:使⽤bool(对象)的时候⾃动触发
功能:强转对象
参数:⼀个self接受当前对象
返回值:必须是布尔类型
类似的还有如下(了解):
__complex__(self) # 被complex强转对象时调⽤
__int__(self) # 被int强转对象时调⽤
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论