# class A(object): # def __init__(self, *args, **kwargs): # print("init 方法id self {}".format(id(self))) # self.attr = 'Hello, world!' # # def __new__(cls, *args, **kwargs): # print("new 方法id cls {}".format(id(cls))) # self = object.__new__(cls) # print("new 方法id self {}".format(id(self))) # return self # # # onj = A() """ 运行结果 new 方法id cls 2235268999616 new 方法id self 2235301196752 init 方法id self 2235301196752 总结 1、__new__和__init__之间的区别 1、__nwe__创建实例对象之前被调用,实例化对象self,第一个参数cls到类对象被分配, 2、__init__ 创建实例对象之后被调用,初始对象self ,第一个参数来自于实例对象被分配。 3、__new__ 至少要一个参数 cls ,代表实例化的类,此参数是实例化的实话由python 解释器提供 4、__new__ 必须有返回值,返回实例化cls出来的实例,还可以return 父类__new__出来的实例,或者直接object的__new__出来的实例 5、__init__有一个参数self ,是由__new__出来的实例,__init__是在创建出实例的时候初始化了动作,不需要返回值。 """
""" 2.何时使用__new__? 1、我想初始化不可变的 (不可变的是什么?https://www.cnblogs.com/Xingtxx/p/12819425.html) 2、我想实现单列 (单例? https://www.cnblogs.com/Xingtxx/p/12819447.html) 3、当你基于参数切换类 (元类引入? https://www.cnblogs.com/Xingtxx/p/12819412.html) 4、使用namedtuple函数实际定义一个不可变的类.介绍__new__继承元组的不可变类的简单用法本页 https://docs.python.org/ja/3/library/collections.html#collections.namedtuple。 """
""" 3.创建实例。 1、在研究继承元组的类之前,回顾super的动作。 2、__new__该方法创建一个实例。 __init__该方法初始化实例。 """ # # __init__ 把实例slef 分配了给第一个参数,因此无需创建实例,只需要把属性分配给一个值 # def __init__(self): # <--- self 实例被代入 # print('__init__:', str(id(self))) # self.attr = 'Hello, world!' # # # # 另一方面,__new__您必须自己创建实例。然后创建实例return # def __new__(cls): # self = object.__new__(cls) # print('__new__ :', str(id(self))) # return self # # # # 在父类中调用方法时 super()要使用 # class Cls(object): # def __new__(cls): # self = super().__new__(cls) # # # # super 是在执行多重继承时将父类的方法,调用为良好的Shioume的函数。 # # 这一次不是多重继承, super().__new__(cls)因为object.__new__(cls)还有,是一样的。 # # super()简写形式 # class Cls(object): # def __new__(cls): # self = super(cls, cls).__new__(cls)
""" 4、继承元组 """ # 1、 当元组继承时,不能初始化它,因为元组不能 以不变的方式进行改变 # ImmutableRegion 一个代表矩形类,假设你希望此类不仅具有(x1 ,y1,x2,y2) 表示坐标,is_dot 表示标点,is_line 表示线,is_rectangle 表示属性 # 假设它是您要预先定义的属性,而不是方法,因为您会经常引用它。 # class ImmutableRegion(tuple): # def __init__(self, args): # x1 = self[0] # y1 = self[1] # x2 = self[2] # y2 = self[3] # width_0 = (x1 - x2 == 0) # height_0 = (y1 - y2 == 0) # is_rectangle = (not width_0 and not height_0) # 0 0 # is_line = (width_0 != height_0) # 0 1 or 1 0 xor # is_dot = (width_0 and height_0) # 1 1 # self[4] = is_rectangle # <--- TypeError # self[5] = is_line # self[6] = is_dot # # # immutable_region = ImmutableRegion((2, 3, 3, 4)) """ 运行结果 这里的问题是元组是不可变的,因此您不能更改元素... __new__使用它 Traceback (most recent call last): File "C:/Users/tangxx/Desktop/pojects/python设计模式/pyhon__new__方法.py", line 98, in <module> immutable_region = ImmutableRegion((2, 3, 3, 4)) File "C:/Users/tangxx/Desktop/pojects/python设计模式/pyhon__new__方法.py", line 93, in __init__ self[4] = is_rectangle # <<<<<TypeError TypeError: 'ImmutableRegion' object does not support item assignment """ # 用__new__初始化 class ImmutableRegion(tuple): def __new__(cls, args): x1 = args[0] y1 = args[1] x2 = args[2] y2 = args[3] width_0 = (x1 - x2 == 0) hight_0 = (y1 - y2 == 0) is_rectangle = (not width_0 and not hight_0) is_line = (width_0 != hight_0) is_dot = (width_0 and hight_0) # super().__new__() # 同于下 self = tuple.__new__(cls, (x1, y1, x2, y2, is_rectangle, is_line, is_dot ,)) return self immutable_region = ImmutableRegion((2, 3, 3, 4)) print(immutable_region) """ 运行结果 (2, 3, 3, 4, True, False, False) """
# 5.使用属性来引用属性。 # 对话模式>>可以复制。 class ImmutableRegion(tuple): def __new__(cls, args): x1 = args[0] y1 = args[1] x2 = args[2] y2 = args[3] width_0 = (x1 - x2 == 0) height_0 = (y1 - y2 == 0) is_rectangle = (not width_0 and not height_0) # 0 0 is_line = (width_0 != height_0) is_dot = (width_0 and height_0) # super().__new__(cls) # 同上 self = tuple.__new__(cls, (x1, y1, x2, y2, is_rectangle, is_line, is_dot)) return self def __repr__(self): x1, y1, x2, y2 = self.x1, self.y1, self.x2, self.y2 return type.__name__ + f"{x1,y1,x2,y2}" x1=property(lambda self:self[0]) y1=property(lambda self:self[1]) x2=property(lambda self:self[2]) y2=property(lambda self:self[3]) is_rectangle=property(lambda self:self[4]) is_line=property(lambda self:self[5]) is_dot=property(lambda self:self[6]) immitable_region=ImmutableRegion((2,3,3,4)) print(immitable_region) print(immitable_region.is_rectangle) print(immitable_region.is_line) print(immitable_region.is_dot) """ 运行结果 type(2, 3, 3, 4) True False False """