魔术方法★★★★★★

### __init__魔术方法

#__init__魔术方法(构造方法)只要父类或者子类中有init 必须在实例化对象的时候给与初始化参数,否则报错★★★★★,
#如果init中给出self外其他参数,就可以直接在类内调用,如果没有,就用传进来的参数
#除了self本身,有几个参数要传几个参数,一一对应
'''
	触发时机:实例化类生成对象,初始化的时候触发
	功能:为对象添加成员
	参数:参数不固定,至少一个self参数
	返回值:无
'''

(1) 基本语法

class MyClass():
	def __init__(self):
		print(11)
		self.name = "张婕"
		print(22)

实例化对象

print(33)
obj = MyClass()
print(44)
print(obj.name)
print(55)

(2) 带有多个参数的构造方法

class MyClass():
	def __init__(self,name):
		# 对象.成员属性(自定义) = 参数值
		self.name = name

实例化 (如果构造方法里面含有额外参数,在实例化时,需要传参)

obj = MyClass("刘")
print(obj.name)

(3) 类可以是1个,对象可以是多个,可以通过一个类实例化多个不同的对象

"""每创建一个对象,都会单独占用一个空间,创建的越多,占用的空间就越大"""
class Children():
	def __init__(self,name,skin):
		self.name = name
		self.skin = skin

	def cry(self):
		print("小孩下生直接哭~")

	def drink(self):
		print("小孩下生直接吸奶奶~")

	def __eat(self):
		print("小孩自己吃自己的手指")
	
	def pub_func(self):
		print("该对象的名字是{},该对象的肤色是{}".format(self.name,self.skin))

	# 注意点
	def pub_func2(self,name,skin):
		print("该对象的名字是{},该对象的肤色是{}".format(name,skin))
		不能直接写name,要用self调用才可以

创建第一个对象

afanda = Children("王铁锤","蓝色")
afanda.cry()
afanda.pub_func()

创建第二个对象

dan = Children("王钢蛋","黑色")
dan.drink()
dan.pub_func()

### new 魔术方法

#一般用于单态时才会用new★★★★★
#要借助父类object 类.方法() 才能创建一个全新的本类对象  例如;obj = object.__new__(cls)
#通过new可以返回不同的对象.可以是自己的 ,可以是其他人的,也可以不返回
#返回自己的对象,要借助父类的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)
print(obj.a)

(2) new方法的触发时机要快于init

"""
__new__  用来创建对象,创建本类对象要借助父类new
__init__ 用来初始化对象(前提的有对象)
先创建对象,再去初始化对象,所以new快于init
"""
class Boat():
	def __init__(self):
		print(2)
	
	def __new__(cls):
		print(1)
		return object.__new__(cls)
obj = Boat()

(3) new方法的参数要和init方法参数一一对象

一个参数

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__构造方法"""
class MyClass():
	a = 1
other_obj = MyClass()

class Boat():
	def __new__(cls):
		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 

"""
有这个对象直接返回,没这个对象,就给你创建,保证只有一个
第一次实例化时,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("小强")
obj2 = Singleton('校长')
print(obj1.name)
print(obj2.name)
结果都是校长
"""
obj1 = Singleton("小强") self.name = "小强"
obj2 = Singleton("校长") self.name = "校长"

obj1 和 obj2 都是同时指向同一个对象,因为对象只创建了一个
对象.name  是获取他后边校长那个值(替换),是同一个值打印了2次;

“”"

### del 魔术方法(析构方法)

'''
	#一般用于查看文件★★★★★
	触发时机:当对象被内存回收的时候自动触发[1.页面执行完毕回收所有变量 2.所有对象被del的时候]
    功能:对象使用完毕后资源回收
	参数:一个self接受对象
	返回值:无
'''
class LangDog():
	food = "吃肉"
	def __init__(self,name):
		self.name = name
	
	def __del__(self):
		print("析构方法被触发..")
	
#(1) 页面执行完毕回收所有变量
obj = LangDog("刀疤")
print(obj.name)

#(2) 所有对象被del的时候
"""
当一个值,没有任何变量指向或者说引用,这个值才会被真正的释放
"""
other_obj = obj
print("<==start==>")
del obj
del other_obj
print("<==end==>")

模拟文件操作(del可以做事后工作)

fp = open(文件,模式,编码)
fp.read()
fp.close()
import os
class ReadFile():
	def __new__(cls,filename):
		#new是创建一个对象,创建的时候可以先判断文件有没有
		# 判断文件是否存在
		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):		
		# 读取文件操作
		content = self.fp.read()
		return content
	
	def __del__(self):
		self.fp.close()
		
obj = ReadFile("ceshi.txt")
res = obj.readcontent()
print(res)

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

###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)
	
# 在系统底层,如果定义了repr , 将会默认赋值给str方法.
# __str__ = __repr__
repr强转obj对象时触发		
obj = Mouse("杰瑞")
res = repr(obj)
print(res)
注意点 底层存在赋值调用给str的语法,所以能实现打印或者str强转对象的触发机制.
print(obj)
res = str(obj)
print(res)

###call 魔术方法

#如果类中方法比较多,对象调用起来麻烦,可以用call,把方法集中(调)到call里面通一调用,有参数要带上参数★★★★★
#可以模拟内置方法★★★★★
'''
触发时机:把对象当作函数调用的时候自动触发,(对象中的参数要和call一一对应,call不包括sell参数,要一一对应)
功能: 模拟函数化操作
参数: 参数不固定,至少一个self参数
返回值: 看需求
'''

(1) 基本用法

class MyClass():
	a = 1
	""""""
	def __call__(self):
		print("call魔术方法被触发..")	

obj = MyClass()
obj()

(2) 模拟洗衣服的过程

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.step1("裤衩")
obj.step2()
obj.step3()
obj.step3()

(3) 模拟内置方法 int 实现myint

import math
class MyInt():

	def mycalc(self,num,sign=1):
		#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:
				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.mycalc(num[1:],sign)
				#调用的时候要把操作的数据写到调用参数中,然后要与调用函数(除了self参数)的参数一一对应,函数操作以后,将调用参数的值赋给函数参数
				#如果调用的时候没有参数就不用写
				#在类的内部,函数除了self参数要一一对应,在外部,对象可以作为一个参数与self对应,在类的内部调用要用self调用
			
			elif num.isdecimal():
				return self.mycalc(num)
			
			else:
				return "老铁,这个真不能转~"
				
	

myint = MyInt()
print(  myint(0)  ) #=> 3
print(  myint(3.13)  ) #=> 3
10 * 1   = 10
10 * -1  = -10
print(eval("3"))
strip
lstrip	
rstrip

### __bool__魔术方法

'''
触发时机:使用bool(对象)的时候自动触发
功能:强转对象
参数:一个self接受当前对象
返回值:必须是布尔类型


类似的还有如下等等(了解):
__complex__(self)      被complex强转对象时调用
__int__(self)          被int强转对象时调用
__float__(self)        被float强转对象时调用
...


class MyClass():
	def __bool__(self):
		return True
	
obj = MyClass()
res = bool(obj)
print(res)

add 魔术方法 (与之相关的__radd__ 反向加法)

'''
触发时机:使用对象进行运算相加的时候自动触发
功能:对象运算
参数:二个对象参数
返回值:运算后的值


类似的还有如下等等(了解):
__sub__(self, other)           定义减法的行为:-
__mul__(self, other)           定义乘法的行为:
__truediv__(self, other)       定义真除法的行为:/
...


class MyAdd():
	def __init__(self,num):
		self.num = num

	# 对象在加号+左侧的时,自动触发
	def __add__(self,other):
		return self.num + other
	#对象在+号右侧时,自动触发
	def __radd__(self,other):
		return self.num + other*2

a = MyAdd(7)
情况一
res = a + 7
self 接受a   other接受7 , 触发的是__add__方法


情况二
res = 7 + a
self 接受a   other接受7 , 触发的是__radd__方法


情况三
"""
a+b 先触发 __add__  ,self 接受的7 , other 接受的是b
res = 7+b

7+b 再触发 __radd__ ,self 接受的b , other 接受的是7
return  8+7*2 = 22
res = 22

"""
b = MyAdd(8)
res = a+b

len 魔术方法

'''
触发时机:使用len(对象)的时候自动触发 
功能:用于检测对象中或者类中成员的个数
参数:一个self接受当前对象
返回值:必须返回整型


类似的还有如下等等(了解):
__iter__(self)                 定义迭代容器中的元素的行为
__reversed__(self)             定义当被 reversed() 调用时的行为
__contains__(self, item)       定义当使用成员测试运算符(in 或 not in)时的行为


''' 

计算一下类中所有自定义成员的个数

思路:__dict__查看内部成员结构,有自定义的和系统自带的(两边是双下划线属于系统自带的),返回是一个字典,通过for循环,可以得到字典的键,然后过滤掉左右两边有下划线的键,把剩下的键添加到新的列表里通过len就可以得到长度★★★★★

class MyClass():
	pty1 = 1
	pty2 = 2
	__pty3 = 3

	def func1():
		pass
	
	def func2():
		pass
	def __func3():
		pass

	def func4():
		pass
	
	def __len__(self):
		# print(MyClass.__dict__)
		# lst = []
		# for i in MyClass.__dict__:
			# print(i)
			# if not(  i.startswith("__") and i.endswith("__")  ):
				# lst.append(i)
			
		# print(lst)	
		
		# 简写
		lst = [i for i in MyClass.__dict__ if not(  i.startswith("__") and i.endswith("__")  )]
		return len(lst)
	
obj = MyClass()
print(   len(obj)  )
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python的魔术方法是以双下划线开头和结尾的方法,也被称为Magic Method(魔术方法)。这些方法在Python中具有特殊的功能和行为。魔术方法包括类的初始化方法__init__、比较方法、数值处理方法、普通算术操作符等等。魔术方法的作用是为了增强类的功能和灵活性,使对象能够具有更复杂的行为和操作。比如__init__方法用于初始化一个对象的状态,__str__方法定义了对象在被str()函数调用时的行为,__repr__方法定义了对象在被repr()函数调用时的行为等等。通过合理使用魔术方法,我们可以更好地控制和定制自己的类和对象的行为。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [python的魔术方法大全](https://blog.csdn.net/qq_40236497/article/details/125539436)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *2* [Python魔术方法详解](https://download.csdn.net/download/weixin_38501610/12879041)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值