pyhon__new__方法.py

# 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

"""

 

posted @ 2020-05-02 20:24  Xingtxx  阅读(244)  评论(0编辑  收藏  举报