简单使用案例一
注意:UpdateList核心代码放到了文章最底部
# 举例一:最简单的使用方式,UpdateList提供四个钩子回调可以灵活自定义各种使用方式
box = UpdateList([{"key": "1", "count": 1}, {"key": "2", "count": 1}, {"key": "3", "count": 1}])
print(box[1]) # 输出:{'key': '2', 'count': 1},默认情况和list没有区别
box.key = "key" # 为UpdateList定义对象key值,之后查询和设置都将通过子项key进行操作
print(box['2']) # 输出:(1, {'count': 1, 'key': '2'}) 元组(索引值,对象内容)
# 使用update方法之前必须定义on_update事件回调
def on_update(old, new):
old["count"] += new["count"]
return old
box.on_update = on_update
box.update({"key": "2", "count": 12})
box.update({"key": "5", "count": 1})
print(box)
# 输出:[{'key': '1', 'count': 1}, {'key': '2', 'count': 13}, {'key': '3', 'count': 1}, {'key': '5', 'count': 1}]
# 插入一个新内容,更新一个旧内容
复杂使用案例二
根据坐标进行区间索引,动态生成扩张区域并通过UpdateList更新或插入
def extension(position):
"""
扩张坐标区域
:param position: 位置系数
:return: 拓张区域范围值
"""
return position - 10, position + 10
def on_key(val, key):
"""
当前val值,key值
:param val:
:param key:
:return:
"""
return val["max"] > key > val["min"]
def on_fetch_key(item):
"""
传入一个item返回key值
:param item:
:return:
"""
return item["x"]
def on_update(old, new):
"""
定义如何更新数据
:param old: 旧数据
:param new: 新数据
:return: 更新的数据
"""
old["item"].append(new)
return old
def on_append(val):
"""
自定义如何增加数据格式
:param val: 传入数据格式
:return: 添加数据
"""
mi, ma = extension(val["x"])
return {"min": mi, "max": ma, "item": []}
box = UpdateList([])
# box.key = "key"
box.key = on_key
box.on_fetch_key = on_fetch_key
box.on_update = on_update
box.on_append = on_append
box.update({"x": 6})
box.update({"x": 7})
box.update({"x": 8})
box.update({"x": 125})
box.update({"x": 126})
box.update({"x": 127})
print(box)
UpdateList类型核心代码
class UpdateList(list):
"""
主要方法update(),该方法是对list类型拓展,
当update的数据对象存在时对其更新,注意请保证UpdateList
的子项是dict类型而不要使用值类型,值类型对于UpdateList毫无意义
on_update hook函数,接收old_val(旧数据), p_object(新数据),需要返回更新数据
on_append hook函数,接收p_object(添加数据),需要返回添加数据
on_fetch_key hook函数,当key属性定义为函数时需要同时定义如何捕获key值
key 支持字符串,字符串指定子元素中的更新参考值
支持函数,接收val(当前数据),key(参考key值)该key值由on_fetch_key返回,函数返回bool值True为更新,False为添加
on_fetch_key作用::
复杂场景下我们可能需要up[("home2", True)]这样来找到响应的item,这样显示传递key值没有什么问题,key函数可以获取到
相应的key数据以供我们处理,但是当我们调用update时,update需要判断该内容是更新还是添加,这时我们传入的内容是数据,显然
update无法知晓如何获取我们想要的类型key值,如("home2", True),所以我们要定义on_fetch_key来告知update如何捕获我们
想要的类型的key值,on_fetch_key只有当key属性定义为函数时才有意义。
"""
def __init__(self, *args, **kwargs):
super(UpdateList, self).__init__(*args, **kwargs)
# 对象key值,可以是函数,函数接收val, key返回布尔值代表满足条件
self.key = None
# 当key设置为函数时必须定义的回调,传入item对象返回该对象key值内容
self.on_fetch_key = None
# 当元素是更新时调用的更新方法,如果元素是插入时不调用,如果不定义该回调默认直接替换
self.on_update = None
# 当元素update方法触发的是添加时调用的回调函数,可以自定义append类型
self.on_append = None
def __getitem__(self, key):
if isinstance(self.key, str):
return self.find(lambda val: val[self.key] == key)
elif hasattr(self.key, "__call__"):
return self.find(lambda val: self.key(val, key))
else:
return super(UpdateList, self).__getitem__(key)
def __setitem__(self, key, value):
if isinstance(self.key, str):
key = self.find(lambda val: val[self.key] == key)[0]
elif hasattr(self.key, "__call__"):
key = self.find(lambda val: self.key(val, key))[0]
super(UpdateList, self).__setitem__(key, value)
def update(self, p_object):
"""
类似于append方法,不同的是当内容存在时会对内容进行更新,更新逻辑遵从update_callback
而当内容不存在时与append方法一致进行末尾加入内容
:param p_object: 内容对象
:return: None
"""
if not self.on_update:
self.on_update = lambda o, p: p
old_val = None
if isinstance(self.key, str):
key = p_object.get(self.key) or -1
if key != -1:
key, old_val = self.find(lambda val: val[self.key] == key)
elif hasattr(self.key, "__call__"):
try:
key, old_val = self.find(lambda val: self.key(val, self.on_fetch_key(p_object)))
except TypeError:
raise TypeError("Function `on_fetch_key` is not defined")
else:
raise TypeError("`key` is TypeError")
if key == -1:
if self.on_append:
self.append(self.on_append(p_object))
else:
self.append(p_object)
else:
super(UpdateList, self).__setitem__(key, self.on_update(old_val, p_object))
def find(self, callback):
"""
返回满足回调函数的内容
:param callback: 回调函数,返回布尔类型用于判断是否满足要求
:return: (索引,值)
"""
for index, item in enumerate(self):
if callback(item):
return index, item
return -1, None
网友评论