Skip to content

Commit

Permalink
[2020-10-03]迁回UpdateList类
Browse files Browse the repository at this point in the history
  • Loading branch information
SystemLight committed Oct 3, 2020
1 parent f7356e9 commit 474c722
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 10 deletions.
2 changes: 1 addition & 1 deletion madtornado4/core/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
VERSION = "4.0.1"
VERSION = "4.0.2"
12 changes: 7 additions & 5 deletions madtornado4/core/register.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from collections import defaultdict
from typing import List, Union
from typing import List, Union, Callable


def api_method(method):
Expand Down Expand Up @@ -30,6 +30,8 @@ async def wrap(self, *args):
new_args.append(args[i])
result = await method(self, *new_args)
result = {} if result is None else result
if "mvc.models" in str(result):
result = result.__dict__
self.write(result)
return result

Expand Down Expand Up @@ -108,11 +110,10 @@ def uri(path: str, *args) -> str:
return path.format(**ArgType.__dict__)


def create_router(prefix: str):
def create_router(prefix: str, use_uri: bool = False) -> Callable[[Union[List[str], str]], List]:
"""
创键router函数,该函数用于包裹__urls,
添加公用前缀
创键router函数,该函数用于包裹__urls,添加公用前缀
举例::
Expand All @@ -123,6 +124,7 @@ def create_router(prefix: str):
__urls = [router("/test")]
:param prefix: 公用url前缀
:param use_uri: 是否使用URI函数解析路径
:return: router函数
"""
Expand All @@ -134,7 +136,7 @@ def __router(urls: Union[List[str], str]):
new_urls = []
for url in urls:
new_urls.append("/" + prefix.strip("/") + "/" + url.lstrip("/"))
return new_urls
return map(uri, new_urls) if use_uri else new_urls

return __router

Expand Down
98 changes: 98 additions & 0 deletions madtornado4/core/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,3 +112,101 @@ def default(self, obj):
return deal_with(obj)
else:
return super(AdvancedJSONEncoder, self).default(obj)


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
12 changes: 8 additions & 4 deletions madtornado4/mvc/controllers/example.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from core.register import api_method, create_router
from mvc.controllers import ApiController
from mvc.models import example

api_router = create_router("/api")
api_router = create_router("/api", use_uri=True)


class Example(ApiController):
Expand All @@ -12,11 +13,14 @@ class Example(ApiController):
"""

__urls = api_router(["/example"])
__urls = api_router(["/example/{Word}"])

@api_method
async def get(self):
return {"hello": "example"}
async def get(self, word):
if word == "model":
return example.Elves()
else:
return {"hello": "get"}

async def post(self):
self.write({"msg": "Example"})

0 comments on commit 474c722

Please sign in to comment.