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

案例:

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

[1, -2, 'xxx', 7, [1, 'oo'], 9] >> (1, 7, 9)

Python
# -*- coding: utf-8 -*- """ @author:songhao @file: c2.py @time: 2017/12/08 """ class In<span class="wp_keywordlink_affiliate"><a href="https://www.168seo.cn/tag/tuple" title="View all posts in tuple" target="_blank">tuple</a></span>(<span class="wp_keywordlink_affiliate"><a href="https://www.168seo.cn/tag/tuple" title="View all posts in tuple" target="_blank">tuple</a></span>): def __init__(self, iterable): print(self) # 之前也是已经实例化了 # Befor super().__init__() # after # tuple 是不可变的元组 所以要想过滤必须在这之前 def main(): l = [1, -2, 'xxx', 7, [1, 'oo'], 9] d = Intuple(l) print(d) if __name__ == '__main__': main() # /usr/local/bin/python3 "/Users/songhao/Desktop/Python3 入门和进阶/Python file/d11/c2.py" # (1, -2, 'xxx', 7, [1, 'oo'], 9) # (1, -2, 'xxx', 7, [1, 'oo'], 9)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# -*- coding: utf-8 -*-
"""
@author:songhao
@file: c2.py
@time: 2017/12/08
"""
 
 
class Intuple ( tuple ) :
     def __init__ ( self , iterable ) :
         print ( self ) # 之前也是已经实例化了
         # Befor
         super ( ) . __init__ ( )
         # after
#         tuple 是不可变的元组 所以要想过滤必须在这之前
 
 
def main ( ) :
     l = [ 1 , - 2 , 'xxx' , 7 , [ 1 , 'oo' ] , 9 ]
     d = Intuple ( l )
     print ( d )
 
 
if __name__ == '__main__' :
     main ( )
 
# /usr/local/bin/python3 "/Users/songhao/Desktop/Python3 入门和进阶/Python file/d11/c2.py"
# (1, -2, 'xxx', 7, [1, 'oo'], 9)
# (1, -2, 'xxx', 7, [1, 'oo'], 9)

反思如果想修改一定要修改创建这个self的函数内部,什么产生的self呢? 是由 __new__ 方法产生的,那么修改这个__new__方法是不是就可以了呢?
接下来我们尝试下

Python
class IntTuple(tuple): def __new__(cls, iterable): # new方法是init方法之前进行调用的方法 # 生成一个生成式 g = (x for x in iterable if isinstance(x, int) and x > 0) # cls为这个类本身,把参数g交给这个类本身 return super(IntTuple, cls).__new__(cls, g) def __init__(self, iterable): super().__init__() if __name__ == "__main__": l = [1, -2, 'xxx', 7, [1, 'oo'], 9] result = IntTuple(l) print(result) # ➜ d11 python3 c2.py # (1, 7, 9)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class IntTuple ( tuple ) :
     def __new__ ( cls , iterable ) :
         # new方法是init方法之前进行调用的方法
         # 生成一个生成式
         g = ( x for x in iterable if isinstance ( x , int ) and x > 0 )
 
         # cls为这个类本身,把参数g交给这个类本身
         return super ( IntTuple , cls ) . __new__ ( cls , g )
 
     def __init__ ( self , iterable ) :
         super ( ) . __init__ ( )
 
 
if __name__ == "__main__" :
     l = [ 1 , - 2 , 'xxx' , 7 , [ 1 , 'oo' ] , 9 ]
 
     result = IntTuple ( l )
     print ( result )
# ➜  d11 python3 c2.py
# (1, 7, 9)

如果对super()用法不太熟可以参看这片文章




  • zeropython 微信公众号 5868037 QQ号 5868037@qq.com QQ邮箱
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值