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

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

练习需求

我们想自定义一种新类型的元组,对于传入的可迭代对象,我们只保留其中int类型且值大于0的元素

需要定义IntTuple类,继承Tuple类

>>> IntTuple([1,3,-1,0,'abc',['a','b'],9])
(1,3,9)

过程分析

  • 创建元组需要传入一个可迭代的对象
    • 示例说明
    >>> tuple(1,)	# 数字1为整形,不是可迭代对象,创建的时候发生错误。
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: 'int' object is not iterable
    
    >>> tuple([1,2,3,4])	#传入一个列表
    (1, 2, 3, 4)
    
  • 创建元组的过程
    • __init__()初始化元组
      >>> x = tuple([1,2,3]).__init__()
      >>> x	# 无输出,说明通过__init__()初始化的元组是空值
      
      
    • __new__()创建元组
      >>> x = tuple([1,2,3]).__new__(tuple,[1,2,3])
      >>> x	# x元组对象创建成功
      (1, 2, 3)
      
    • 查看__new__()
      在这里插入图片描述
      这里要说明一下,创建元组首先会调用__new__()创建并返回一个对象,返回给__init__()方法,这时将会自动调用__init__()方法

练习实现

根据以上分析,我们要定义的IntTuple类,只需要重写父类的__new__()方法即可,注意:这个方法必须返回一个对象。

  • 代码实现
    class IntTuple(tuple):
        """
        继承tuple类,重写__new__()方法
        对于传入的可迭代对象,我们只保留其中int类型且值大于0的元素
        """
    
        def __new__(cls, iterable):
            # [i for i in iterable if isinstance(i, int) and i > 0] 这里用一个列表推导式筛选
            return super().__new__(cls, [i for i in iterable if isinstance(i, int) and i > 0])
    
    
    demo = IntTuple([1, 3, -1, 0, 'abc', ['a', 'b'], 9])
    print(demo)  # (1, 3, 9)
    
    

最后,有喜欢博主写的内容的伙伴可以收藏加关注哦!

猜你喜欢

转载自blog.csdn.net/weixin_44604586/article/details/106825132