今天学Brython
的时候发现了它的ajax
请求太繁琐了。比如:
from browser import document, ajax
url = "http://api.open-notify.org/iss-Now.json"
msg = "Position of the International Space Station at {}: {}"
def complete(request):
import json
import datetime
data = json.loads(request.responseText)
position = data["iss_position"]
ts = data["timestamp"]
Now = datetime.datetime.fromtimestamp(ts)
document["zone10"].text = msg.format(Now, position)
def click(event): # 就是这个函数的代码,感觉挺没用的,还要敲好几行……一点不符合python的优雅
req = ajax.ajax()
req.open("GET", url, True)
req.bind("complete", complete)
document["zone10"].text = "waiting..."
req.send()
document["button10"].bind("click", click)
这是官方给出的代码,然后我在想怎么将这坨代码搞得精简点。于是我想到了装饰器。鉴于我装饰器基础不是很扎实,但是为了以后敲代码的方便,我打算手撕一个python
库来一行代码解决ajax
的发送问题。为了解决这个问题,我把装饰器学了一遍(都怪我以前偷懒,觉得搞懂原理也没啥用,然后遇到问题了被迫学一遍)。
写这篇博客先主要理解下装饰器。
函数做装饰器
不含参数的装饰器
代码如下:
def hello(func):
def world():
pass
return world
@hello
def a():
print("Hello World!")
装饰器代码等效于:
hello(a)
再精简点,等效于:
world # 对,就是这个函数名
a() # 等效于调用:hello(a)() -> 再等效于调用 world()
这个应该没问题了。
含参的装饰器
这个就直接把我的那个ajax
的例子放出来吧:
from browser import ajax, bind, document
from functools import wraps
def send_ajax(url, method="GET", data=None, sync=True):
def hello(func):
@wraps(func)
def world(*args, **kwargs):
req = ajax.ajax()
req.open(method, url, sync)
req.bind("complete", func)
if data is None:
req.send()
else:
req.send(data)
return world
return hello
然后使用:
from browser import bind, document
from litter_ajax import send_ajax # 导入自己写的包
url = "http://api.open-notify.org/iss-Now.json"
msg = "Position of the International Space Station at {}: {}"
@bind(document['button10'], 'click')
@send_ajax(url, method="GET", data=None, sync=True) # 只用多添加一行代码即可!
def complete(request):
import json
import datetime
data = json.loads(request.responseText)
position = data["iss_position"]
ts = data["timestamp"]
Now = datetime.datetime.fromtimestamp(ts)
document["zone10"].text = msg.format(Now, position)
不过要注意,ajax
要在服务器下才能跨文件执行,可以用Brython
提供的服务器命令:
py -m http.server
这样就可以了!对了,还有关键的没说:
好了,可以继续了。
用类做装饰器
不含参数的装饰器
class Hello:
def __init__(self):
pass
def __call__(self, func):
def world():
pass
return world
对,和函数没啥区别,知道__call__
是干啥的这坨代码就没了。
含参数的装饰器
还是拿我的代码举例子,如下:
class send_ajax:
def __init__(self, url, method="GET", data=None, sync=True):
self.url = url
self.method = method
self.data = data
self.sync = sync
def __call__(self, func):
@wraps(func)
def world(*args, **kwargs):
req = ajax.ajax()
req.open(self.method, self.url, self.sync)
req.bind("complete", func)
if self.data is None:
req.send()
else:
req.send(self.data)
return world
好了,结束了 ~
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。