day23.多态 __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("[空军]高中跳伞,落地成盒")
View Code
# 实例化陆军对象
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
View Code
import abc
class H20(metaclass=abc.ABCMeta):
    def temperature(self):
        pass

class Water(H20):
    def temperature(self):
        print('')        

class Ice(H20):
    def temperature(self):
        print('')
class Steam(H20):
    def temperature(self):
        print('')

例:

class H20:
    def __init__(self, name, temperature):
        self.name = name
        self.temperature = temperature

    def turn_ice(self):
        if self.temperature < 0:
            print('%s 温度太低结冰了' % self.name)
        elif self.temperature > 0 and self.temperature < 100:
            print('%s 液化成水' % self.name)
        else:
            print('%s 温度太高变成的水蒸气' % self.name)

class Water(H20):
    pass
class Ice(H20):
    pass
class Steam(H20):
    pass

w1 = Water('', 25)
i1 = Ice('', -20)
s1 = Steam('水蒸气', 2009)

# w1.turn_ice()
# i1.turn_ice()
# s1.turn_ice()

# 这里是继承,实例出三个对象



def func(obj):
    obj.turn_ice()

# 多态
func(w1)
func(i1)
func(s1)
#执行同一个函数得到不同的值

# 水 液化成水
# 冰 温度太低结冰了
# 水蒸气 温度太高变成的水蒸气

二、__new__魔术方法

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

1、基本语法

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

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

# <class '__main__.MyClass'>
# None

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__ 参数一一对应

3.1、单个参数的情况

class Boat():
    def __new__(cls,name):
        return object.__new__(cls)
    def __init__(self,name):
        self.name = name
        
obj = Boat("友谊的小船说裂开就裂开")
print(obj.name)

3.2、多个参数的情况

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)

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

三、单态模式

"""
一个类,无论实例化多少个对象,都有且只有1个

优点:节省内存空间,提升执行效率,
针对于不要额外对该对象添加成员的场景(比如: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)
print(aaa)
"""
obj1 = SingleTon(宋云杰) self.name = 宋云杰
obj2 = SingleTon(戈隆)   self.name = "戈隆"
self 代表的是本对象

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

obj1.name => 戈隆
obj2.name => 戈隆
"""
"""
戈隆
戈隆
"""
解析
原文地址:https://www.cnblogs.com/kongxiangqun/p/13455713.html