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

任务需求:
'''
我们想定义一种新类型的元祖,对于传入的可迭代对象,
只保留int类型并且值大于0的元素,例如:
IntTuple([1,3,-1,"ab","4",[3,"d"],2]) ==>(1,3,2)
并且IntTuple是内置tuple的子类,如何实现
'''
class IntTuple(tuple):
    def __init__(self, iterable):
        # 我们要在什么地方过滤,调用父类的init方法之前?还是之后?
        # 首先之后肯定是不可能的,因为元祖是不可变类型
        # 那么只能在之前过滤
        super(IntTuple, self).__init__(iterable)


# 我们先来传入参数看一下结果
t = IntTuple([1, 3, -1, "ab", "4", [3, "d"], 2])
print(t)
'''
TypeError: object.__init__() takes no parameters
'''
# 结果报了个TypeError,说object的__init__不需要参数
# 这说明了tuple里面根本就没有__init__,于是调用object的__init__
# 可是tuple里面没有__init__方法的话,那tuple怎么接收参数
# 于是我们想到了这是__new__方法导致的
# 其实元祖在__new__方法的时候就已经创建好了
# 对于列表,[1, 2, 3]这个过程分为两步,首先__new__方法会返回一个[],然后__init__方法返回[1,2,3](将值加到[]中)
# 但对于元祖,(1, 2, 3),在__new__方法的时候直接就返回了(1, 2, 3),而不是先返回(),然后再经过__init__方法返回(1, 2, 3),因为tuple根本没有__init__方法

class IntTuple(tuple):
    # 因此要想修改,只能在调用父类的__new__方法之前修改
    def __new__(cls, iterable):
        iterable = [x for x in iterable if isinstance(x, int) and x > 0]
        # 注意:__new__方法一定要具有返回值
        # 返回值非常固定,super(定义的类,cls).__new__(cls, *args, **kwargs)
        return super(IntTuple, cls).__new__(cls, iterable)


# 然后再来看一下结果
t = IntTuple([1, 3, -1, "ab", "4", [3, "d"], 2])
print(t)

'''
打印的结果是(1, 3, 2)
'''
# 任务完成

猜你喜欢

转载自www.cnblogs.com/traditional/p/9219439.html