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

作者:就是想学习 时间:2021-02-05 19:25:43 

这篇文章主要介绍了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] = 5
print(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'}

来源:https://www.cnblogs.com/sidianok/p/11790087.html

标签:Python,魔法,方法,容器
0
投稿

猜你喜欢

  • pytorch1.0中torch.nn.Conv2d用法详解

    2023-07-17 10:53:48
  • 分别用marquee和div+js实现首尾相连循环滚动效果,仅3行代码

    2024-04-18 10:55:26
  • 浅析Python打包时包含静态文件处理方法

    2023-05-29 01:12:10
  • Web 开发中遇到的UTF-8编码的问题总结第1/2页

    2023-06-09 05:02:10
  • Python 保持登录状态进行接口测试的方法示例

    2023-03-18 17:09:07
  • 文件上传服务器-jupyter 中python解压及压缩方式

    2021-06-03 22:32:21
  • 详解Python多线程Selenium跨浏览器测试

    2023-05-05 08:10:11
  • Python实现大乐透号码随机生成

    2022-09-04 18:46:01
  • Python使用ElementTree美化XML格式的操作

    2022-03-11 05:11:20
  • 阿里巴巴中秋节logo设计的艰辛曲折过程

    2008-09-11 17:15:00
  • Python GUI编程学习笔记之tkinter中messagebox、filedialog控件用法详解

    2022-10-26 19:49:05
  • Python著名游戏实战之方块连接 我的世界

    2022-12-10 06:25:50
  • Python 设计模式中的创建型建造者模式

    2021-05-23 02:41:50
  • 关于useSSL=false和true的区别及说明

    2024-01-25 03:27:40
  • Django项目在pycharm新建的步骤方法

    2021-01-19 11:46:32
  • Django中cookie的基本使用方法示例

    2022-08-13 16:49:05
  • SQL中的连接查询详解

    2024-01-25 08:06:40
  • 深入理解Go语言中的数组和切片

    2024-02-04 05:09:54
  • 互联网产品设计师职业生涯

    2009-04-20 20:41:00
  • ASP程序开发注意的安全事项

    2010-05-03 10:55:00
  • asp之家 网络编程 m.aspxhome.com