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