python-魔术方法_del_str_repr_call_类相关的魔术属性

魔术方法

1. _del_ 析构方法

'''
	触发时机:当对象被内存回收的时候自动触发
	[1.页面执行完毕回收所有变量 2.所有对象被del的时候]
    功能:对象使用完毕后资源回收
	参数:一个self接受对象
	返回值:无
'''

class LangDog():
	food = "改吃蔬菜"
	def __init__(self,name):
		self.name = name
	
	def __del__(self):
		print("析构方法被触发")
		
obj = LangDog("肉丝")

# 1.页面执行完毕回收所有变量 
"""
print(obj.name)
"""

# 2.所有对象被del的时候
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("没有该类文件")

2. _str_ 和 __repr__

#__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__ 魔术方法
'''
	触发时机: 使用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)

3. _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

4. _bool_ __len__ __add__

# __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
}
"""

5. 与类相关的魔术属性

'''
# __dict__ 获取对象或类的内部成员结构
# __doc__  获取对象或类的内部文档
# __name__ 获取类名函数名
# __class__ 获取当前对象所属的类
# __bases__ 获取一个类直接继承的所有父类,返回元组
'''

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("这一手招数,只能我自己用")
	
# __dict__ 获取对象或类的内部成员结构
obj = Children()
print(obj.__dict__)
print(Children.__dict__)


# __doc__  获取对象或类的内部文档
print(obj.__doc__)
print(Children.__doc__)

# __name__ 获取类名函数名
def func111():	
	print("我是func111方法")
# 获取函数名
obj.moonread(func111)
# 获取类名
obj.moonread(Man)

# __class__ 获取当前对象所属的类
print(obj.__class__)

# __bases__ 获取一个类直接继承的所有父类,返回元组
print(Children.__bases__)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

I believe I can fly~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值