侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

Python魔法方法 容器部方法详解

Python  /  管理员 发布于 7年前   249

这篇文章主要介绍了Python魔法方法 容器部方法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

为了加深印象,也为了以后能够更好的回忆,还是记录一下。

序列(类似集合,列表,字符串),映射(类似字典)基本上是元素的集合,要实现他们的基本行为(协议),不可变对象需要两个协议,可变对象需要4个协议。

  • __len__(self):返回元素的数量,(为不可变对象需要的协议之一)=====> len
  • __iter__返回一个迭代器,具有了__next__方法后,给for使用。
  • __contains__ 代表 in的意思 xx.__contains__ (22) ==>22 in xx一个效果
  • __getitem__(self, key)或者__getitem__(self, index), 返回执行输入所关联的值(为不可变对象需要的协议之一)
  • __setitem__(self, key, values) 或者 __setitem__(self, index, values) , 设置指定输入的值对应的values
  • __delitem__ (self, key) 删除指定key的值
  • __missing__这个有意思,跟__getattr__有的一比,是找不到这个key,触发条件。前面用列表测试了,晕死了(只对字典有效。)
  • __del__, 析构函数当这个类不存在实例对象时执行。

下面我编写一个自定义类似列表的类,实例后该类默认前面有10个None参数,且不能删除前面5个空None。(随口说的,开始写了)

def check_index(index):  if index < 5:    raise IndexError('index must greater than 10')  class S_List:  def __init__(self):    self.ll = [None] * 10   def __len__(self): # 提取参数长度    return len(self.ll)   def __getitem__(self, index): # 取出参数    return self.ll[index]   def __setitem__(self, index, value): # 设置参数    check_index(index)    self.ll[index] = value   def __delitem__(self, index):    check_index(index)    self.ll.pop(index)   def __str__(self): # 打印对象时,输出列表本身    return str(self.ll)   def __del__(self): # 没有手工删除在程序结束时释放    print('我被释放了!') sl = S_List()del sl[3] print(isinstance(sl, S_List))print(f'输出原始数据:{sl}')sl[6] = 'six'print(f'修改后原始数据:{sl}')print(f'随便取一个值:{sl[1]}')del sl[6]print(f'第二次修改后原始数据:{sl}')del sl[3]# sl[4] = 'oh'print(sl)

正常输出:

True输出原始数据:[None, None, None, None, None, None, None, None, None, None]修改后原始数据:[None, None, None, None, None, None, 'six', None, None, None]随便取一个值:None第二次修改后原始数据:[None, None, None, None, None, None, None, None, None][None, None, None, None, None, None, None, None, None]我被释放了!

报错提示:

Traceback (most recent call last): File "/Users/shijianzhong/Desktop/yunzuan_buy/study_base.py", line 81, in <module>  del sl[3] File "/Users/shijianzhong/Desktop/yunzuan_buy/study_base.py", line 73, in __delitem__  check_index(index) File "/Users/shijianzhong/Desktop/yunzuan_buy/study_base.py", line 53, in check_index  raise IndexError('index must greater than 10')IndexError: index must greater than 10我被释放了!

这个是自定义的一个基本没有什么方法的伪字典,不能增加元素,而且index,count等方法由于没有写入都无法使用。

好的方式是可以继承list或者dict的类,在里面对需要的条件进行修改限制,这样的话,实例出来的对象可以继承原来的全部方法。

插入一个直接不用初始化自定义变量,直接借用__dict__来实现伪字典型的取值复制。

class Ii:  def __getitem__(self, item):    return self.__dict__[item]  def __setitem__(self, key, value):    self.__dict__[key] = value li = Ii()li[3] = 5print(li[3]) # 5

这次我可以正真的定义个超级列表,根据我的需要。现在要求这个列表初始化有5个None元素,前面5个元素不能修改,后面添加的元素必须为str

def check_str(params):  if not isinstance(params, str):    raise ValueError('parameters must is string')   def check_index(index):  if index < 5:    raise IndexError('index must greater than 10') class Super_List(list):  def __init__(self):    super(Super_List, self).__init__()   # 调用父类初始化    self += [None] * 5           # 对初始化的参数进行修改   def append(self, *args):          # 对append进行参数限制    for i in args:      check_str(i)    return super(Super_List, self).append(*args)   def insert(self, index, *args):       # 对insert的参数(索引及插入元素)进行限制    check_index(index) # 判断插入位置    for i in args:      check_str(i)    return super(Super_List, self).insert(index, *args)   def extend(self, *args):          # 对扩张的列表元素进行判断    temp = args[0]    for i in temp:      check_str(i)    super(Super_List, self).extend(*args)     def __delitem__(self, index):        # 对del命令的索引进行判断    check_index(index)    super(Super_List, self).__delitem__(index)   def clear(self):  # 禁止使用clear命令    raise TypeError('No permission') ss_l = Super_List()print(ss_l)ss_l.append('1')ss_l.insert(5, 'a')ss_l.extend(['a', 'b', 'c'])ss_l.clear()print(ss_l)

写了快半个小时,感觉列表的增加与删除命令很多,所有有一些命令没有重写,但逻辑还是一样的。

如果向在有人访问参数的时候,自动执行某些命令,可以写在__getitem__下面。

跟新后,添加一个__missing__感觉还是非常有意思的。

class Dict(dict):  def __init__(self, *args, **kwargs):    # self.x = 12    super(Dict, self).__init__(*args, **kwargs)   def __missing__(self, key):    self[key] = None    return self[key]l = Dict(((1,2),(2,3)))print(l)print(l[8])print(l)
{1: 2, 2: 3}None{1: 2, 2: 3, 8: None}

有点像字典的内置方式setdefault,我看能不能改成一样的。

已经写完了,通过[]取值。

# -*- coding: utf-8 -*-class Dict(dict):  def __init__(self, *args, **kwargs):    super(Dict, self).__init__(*args, **kwargs)  def __missing__(self, item):    # 判断进来的参数是不是字符串,如果是字符串说明就是对象主动调用__missing__进来的    # 非__getitem__导入的    if isinstance(item, str):      self[item] = 'Default Empty'      return self[item]    # 如果对象非字符串,明显说明是__getitem__导入的,判断长度就可以    else:      key, value = item      self[key] = value   # 自身进行赋值      return self[key]   # 返回value  def __getitem__(self, item):    if not isinstance(item, tuple):  # 传进来的item进行判断,如果非元祖,直接调用父类绑定self方法返回      return super(Dict, self).__getitem__(item)    elif len(item) == 2 and isinstance(item, tuple):  # 如果是元祖,又是2位长度的,进行赋值。其实感觉元祖判断没有好像也没关系      k, _ = item      if k in self:        return super(Dict, self).__getitem__(k)   # 如果k在self里面继续调用父类绑定self方法返回      else:        res = self.__missing__(item)       # 否则调用自身的__missing        return res    else:      raise TypeError('input pattern error')     # 元素数量超过2个,直接报错l = Dict((('name','sidian'),('age',99)))print(l)print(l['name','wudian'])print(l['addr','杭州'])print(l['hobby'])print(l)
{'name': 'sidian', 'age': 99}sidian杭州Default Empty{'name': 'sidian', 'age': 99, 'addr': '杭州', 'hobby': 'Default Empty'}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


  • 上一条:
    Python读取csv文件实例解析
    下一条:
    python读取raw binary图片并提取统计信息的实例
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 在python语言中Flask框架的学习及简单功能示例(0个评论)
    • 在Python语言中实现GUI全屏倒计时代码示例(0个评论)
    • Python + zipfile库实现zip文件解压自动化脚本示例(0个评论)
    • python爬虫BeautifulSoup快速抓取网站图片(1个评论)
    • vscode 配置 python3开发环境的方法(0个评论)
    • 近期文章
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • PHP 8.4 Alpha 1现已发布!(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2018-04
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2022-01
    • 2023-07
    • 2023-10
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客