0805Python总结-多态,__new__魔术方法,单态模式

一.多态

不同的子类对象,调用相同的父类方法,产生不同的执行结果
关键字: 继承, 改写

class Soldier():
	def attack(self):
		pass

	def back(self):
		pass
# 陆军
class Army(Soldier):
	def attack(self):
		print("[陆军]搏击,ufc,无限制格斗,太极,八卦,占星,制作八卦符")

	def back(self):
		print("[陆军]白天晨跑10公里,也行800百公里")

# 海军
class Navy(Soldier):
	def attack(self):
		print("[海军]潜泳水下30个小时,手捧鱼雷,亲自送到敌人的老窝,炸掉敌人的碉堡")

	def back(self):
		print("[海军]每小时在海底夜行800公里,游的比鲨鱼还快")

# 空军
class AirForce(Soldier):
	def attack(self):
		print("[空军]空中夺导弹,手撕飞机,在空中打飞机,精准弹幕")

	def back(self):
		print("[空军]高中跳伞,落地成盒")
# 实例化陆军对象
army_obj = Army()
# 实例化海军对象
navy_obj = Navy()
# 实例化空军对象
af_obj = AirForce()
lst = [army_obj, navy_obj, af_obj]
strvar = """
1.所有兵种开始攻击训练
2.所有兵种开始撤退训练
3.空军练习攻击,其他兵种练习撤退
"""
print(strvar)
num = input("将军请下令,选择训练的种类")
for i in lst:
	if num == "1":
		i.attack()
	elif num == "2":
		i.back()
	elif num == "3":
		if isinstance(i, AirForce):
			i.attack()
		else:
			i.back()
	else:
		print("将军~ 风太大 我听不见~")
		break

二.__new__魔术方法

"""
	触发时机:实例化类生成对象的时候(触发时机在__init__之前)
	功能:控制对象的创建过程
	参数:至少一个cls接受当前的类,其他根据情况决定
	返回值:通常返回对象或None
"""

1.基本语法

类.方法(自定义类) => 借助父类object创建MyClass这个类的对象
obj = object.–new–(cls)

class MyClass2():
	pty = 100
obj2 = MyClass2()

class MyClass():
	def __new__(cls):
		print(cls)  # <class '__main__.MyClass'>
		# 类.方法(自定义类) => 借助父类object创建MyClass这个类的对象
		obj = object.__new__(cls)
		# (1)借助父类object创建自己类的一个对象
		# return obj
		# (2)返回其他类的对象
		# return obj2
		# (3)不返回任何对象
		return None

obj = MyClass()
print(obj)  # None
# print(obj.pty)

2.__new__触发时机快与构造方法

__new__ 用来创建对象
__init__用来初始化对象
先创建对象,才能再初始化对象,所以__new__快与__init__
class Boat():
	def __new__(cls):
		print(2)
		return object.__new__(cls)
	def __init__(self):
		print(1)

obj = Boat()  # 2 1

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, color, shangpai):
		self.name = name
		self.color = color
		self.shangpai = shangpai

obj = Boat("泰坦尼克号", "屎绿色", "京A66688")
print(obj.name)  # 泰坦尼克号
print(obj.color)  # 屎绿色
print(obj.shangpai)  # 京A66688

4.注意点

如果返回的对象不是自己本类中的对象,不会触发本类的构造方法

class MyClass():
	pty = 200
obj = MyClass()

class Boat():
	def __new__(cls, *args, **kwargs):
		# return object.__new__(cls)
		# return obj
		return None
	def __init__(self):
		print("构造方法被触发")
obj = Boat()
print(obj)  # None

三.单态模式

一个类,无论实例化多少个对象,都有且只有一个
优点:节省内存空间, 提升执行效率
针对于不需要额外对该对象添加成员的场景(比如:mysql增删改查)

1.基本语法

class SingleTon():
	__obj = None
	def __new__(cls):
		if cls.__obj is None:
			# 把创建出来的对象赋值给私有成员__obj
			cls.__obj = object.__new__(cls)
		return cls.__obj

obj1 = SingleTon()
obj2 = SingleTon()
obj3 = SingleTon()
print(obj1, obj2, obj3)
"""
第一次实例化对象的时候,创建一个对象赋值给cls.__obj,返回cls.__obj
第二次实例化对象的时候,判定cls.__obj is None:不成立,直接返回上一次创建好的那一个对象
第三次实例化对象的时候,判定cls.__obj is None:不成立,直接返回上一次创建好的那一个对象
"""

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 = "宋云杰"
obj1 = SingleTon("戈隆") self.name = "戈隆"
self 代表的是本对象

第一次实例化对象的时候,创建一个对象,赋值name为宋云杰
第二次实例化对象的时候,因为 cls.__obj is None 不满足,返回上一个创建好的对象
为上一个实例化对象的name这个属性赋值 为戈隆
obj1 和 obj2 所指代的对象是同一个对象

obj1.name => 戈隆
obj2.name => 戈隆
"""
"""
戈隆
戈隆
"""

猜你喜欢

转载自blog.csdn.net/qq_45957580/article/details/107829269