任务需求:
'''
我们想定义一种新类型的元祖,对于传入的可迭代对象,
只保留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)
'''
# 任务完成