day19-Python运维开发基础(类的魔术方法)

时间:2023-03-09 22:05:48
day19-Python运维开发基础(类的魔术方法)

1. __new__魔术方法

day19-Python运维开发基础(类的魔术方法)

# ###  __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("周永玲") # 传多个参数的情况
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("周玲玲","绿色",108)
print(obj.name) # 注意点:
"""
如果__new__返回的不是自己本类的对象,不会触发构造方法__init__
"""
class MyClass(): def __new__(cls,*args,**kwargs):
print("__new__被触发")
return obj2 def __init__(self):
print("__init__构造方法被触发")
obj = MyClass()

__new__魔术方法 示例代码

# ### 单态模式 : 无论实例化对象多少次,都有且只有一个对象

# (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("李诗韵")
obj2 = Singleton("黄乐锡")
print(obj1.name)
print(obj2.name) """ 第一次实例化的时候, self.name = 李诗韵
第一次实例化的时候, 返回的是第一次实例化出来的对象
将该对象以前的name属性 从李诗韵改成黄乐西
self.name = 黄乐西 打印 obj1.name obj2.name 都是黄乐西 """

单态模式 示例代码

2. 类的魔术方法

day19-Python运维开发基础(类的魔术方法)

# ### 魔术方法 __del__ (析构方法)
'''
触发时机:当对象被内存回收的时候自动触发[1.页面执行完毕回收所有变量 2.所有对象被del的时候]
功能:对象使用完毕后资源回收
参数:一个self接受对象
返回值:无
''' # (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)

__del__析构方法 示例代码

# ###__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("")
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))

__call__魔术方法 示例代码

# ### __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)

__str__魔术方法 示例代码

# ### __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)

__bool / add / len 魔术方法 __ 示例代码

day19