7-1 如何派生内置不可变类型并修其改实例化行为

一、定义一个IntTuple类,继承tuple类这里只是标准的继承未做任何修改,所以IntTuple与tuple一样
class IntTuple(tuple): def __init__(self,iterable): #before print(self) #在调用 __init__时self已经做为参数输入,内置的tuple已经创建好了,此时self已经是不可变的了, super(IntTuple,self).__init__(iterable) #super()第二个参数self要求是当前的一个实例 #after t = IntTuple([1,-1,'abc',6,['x','y'],3]) print(t)
结果输出:
(1, -1, 'abc', 6, ['x', 'y'], 3)
(1, -1, 'abc', 6, ['x', 'y'], 3)
二、实例self实际上是被__new__方法创建出来的,他才是名符其实的构造器方法。__new__方法是一个静态方法,在创建实例时,他先于__init__方法被调用 。
调用__new__得到一个实例,再把这个实例传入到__init__的self。
class IntTuple(tuple): def __new__(cls,iterable): #第一个参数是类对象,创建IntTuple时,IntTuple会传入到第一个参数。其他参数和__init__是一样的,需要几个定义几个,在其内部,同样要调用父类的__new__方法,由父类创建真正的对象。 g=(x for x in iterable if isinstance(x,int) and x>0)#生成器表达式,生成器解析 return super(IntTuple,cls).__new__(cls,g) #super的第二个参数,要求是当前类的一个子类,即cls自身是自身cls的一个子类。父类的__new__方法传入的是要修改的参数,(即过滤后的iterable)过程是先调用 __new__得到一个实例,这个实例再传入到__init__的self。
class IntTuple(tuple): def __new__(cls,iterable): g = (x for x in iterable if isinstance(x,int) and x>0) return super(IntTuple,cls).__new__(cls,g) def __init__(self,iterable): #before print(self) super(IntTuple,self).__init__(iterable) #after t = IntTuple([1,-1,'abc',6,['x','y'],3]) print(t)
输出结果:
(1, 6, 3)
(1, 6, 3)
posted on 2018-05-08 14:51 石中玉smulngy 阅读(196) 评论(0) 收藏 举报
浙公网安备 33010602011771号