Tornado框架入门教程_tornado菜鸟教程

执行python fact.py ,打开浏览器,键入http://localhost:8888/fact?n=50,可以看到浏览器输出了
608281864034267560872252163321295376887552831379210240000000000,如果我们不提供n参数,访问http://localhost:8888/fact,可以看到浏览器输出了400: Bad Request,告诉你请求错误,也就是参数少了一个。

使用Redis

上面的例子是将缓存存在本地内存中,如果换一个端口再其一个阶乘服务,通过这个新端口去访问的话,对于每个n,它都需要重新计算一遍,因为本地内存是无法跨进程跨机器共享的。

所以这个例子,我们将使用Redis来缓存计算结果,这样就可以完全避免重复计算。另外我们将不在返回纯文本,而是返回一个json,同时在响应里增加字段来说名本次计算来源于缓存还是事实计算出来的。另外我们提供默认参数,如果客户端没有提供n,那就默认n=1。

import json
import redis
import tornado.ioloop
import tornado.web


class FactorialService(object):

    def \_\_init\_\_(self):
        self.cache = redis.StrictRedis("localhost", 6379)  *# 缓存换成redis了*
        self.key = "factorials"

    def calc(self, n):
        s = self.cache.hget(self.key, str(n))  *# 用hash结构保存计算结果*
        if s:
            return int(s), True
        s = 1
        for i in range(1, n):
            s *= i
        self.cache.hset(self.key, str(n), str(s))  *# 保存结果*
        return s, False


class FactorialHandler(tornado.web.RequestHandler):

    service = FactorialService()

    def get(self):
        n = int(self.get_argument("n") or 1)  *# 参数默认值*
        fact, cached = self.service.calc(n)
        result = {
            "n": n,
            "fact": fact,
            "cached": cached
        }
        self.set_header("Content-Type", "application/json; charset=UTF-8")
        self.write(json.dumps(result))


def make\_app():
    return tornado.web.Application([
        (r"/fact", FactorialHandler),
    ])

if __name__ == "\_\_main\_\_":
    app = make_app()
    app.listen(8888)
    tornado.ioloop.IOLoop.current().start()

当我们再次访问http://localhost:8888/fact?n=50,可以看到浏览器输出如下
{"cached": false, "fact": 608281864034267560872252163321295376887552831379210240000000000, "n": 50}
,再刷新一下,浏览器输出{"cached": true, "fact": 608281864034267560872252163321295376887552831379210240000000000, "n": 50},可以看到cached字段由true编程了false,表明缓存确实已经保存了计算的结果。我们重启一下进程,
再次访问这个连接,观察浏览器输出,可以发现结果的cached依旧等于true。说明缓存结果不再是存在本地内存中了。

圆周率计算服务

接下来我们再增加一个服务,计算圆周率,圆周率的计算公式有很多种,我们用它最简单的。

我们在服务里提供一个参数n,作为圆周率的精度指标,n越大,圆周率计算越准确,同样我们也将计算结果缓存到Redis服务器中,避免重复计算。

*# pi.py*
import json
import math
import redis
import tornado.ioloop
import tornado.web

class FactorialService(object):

    def \_\_init\_\_(self, cache):
        self.cache = cache
        self.key = "factorials"

    def calc(self, n):
        s = self.cache.hget(self.key, str(n))
        if s:
            return int(s), True
        s = 1
        for i in range(1, n):
            s *= i
        self.cache.hset(self.key, str(n), str(s))
        return s, False

class PiService(object):

    def \_\_init\_\_(self, cache):
        self.cache = cache
        self.key = "pis"

    def calc(self, n):
        s = self.cache.hget(self.key, str(n))
        if s:
            return float(s), True
        s = 0.0
        for i in range(n):
            s += 1.0/(2*i+1)/(2*i+1)
        s = math.sqrt(s*8)
        self.cache.hset(self.key, str(n), str(s))
        return s, False

class FactorialHandler(tornado.web.RequestHandler):

    def initialize(self, factorial):
        self.factorial = factorial

    def get(self):
        n = int(self.get_argument("n") or 1)
        fact, cached = self.factorial.calc(n)
        result = {
            "n": n,
            "fact": fact,
            "cached": cached
        }
        self.set_header("Content-Type", "application/json; charset=UTF-8")
        self.write(json.dumps(result))

class PiHandler(tornado.web.RequestHandler):

    def initialize(self, pi):
        self.pi = pi

    def get(self):
        n = int(self.get_argument("n") or 1)
        pi, cached = self.pi.calc(n)
        result = {
            "n": n,
            "pi": pi,
            "cached": cached
        }
        self.set_header("Content-Type", "application/json; charset=UTF-8")
        self.write(json.dumps(result))

def make\_app():
    cache = redis.StrictRedis("localhost", 6379)
    factorial = FactorialService(cache)
    pi = PiService(cache)
    return tornado.web.Application([
        (r"/fact", FactorialHandler, {"factorial": factorial}),
        (r"/pi", PiHandler, {"pi": pi}),
    ])

if __name__ == "\_\_main\_\_":
    app = make_app()
    app.listen(8888)
    tornado.ioloop.IOLoop.current().start()

因为两个Handler都需要用到redis,所以我们将redis单独抽出来,通过参数传递进去。另外Handler可以通过initialize函数传递参数,在注册路由的时候提供一个字典就可以传递任意参数了,字典的key要和参数名称对应。我们运行python pi.py,打开浏览器访问http://localhost:8888/pi?n=200,可以看到浏览器输出{"cached": false, "pi": 3.1412743276, "n": 1000},这个值已经非常接近圆周率了。

一、Python所有方向的学习路线

Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照下面的知识点去找对应的学习资源,保证自己学得较为全面。

img
img

二、Python必备开发工具

工具都帮大家整理好了,安装就可直接上手!img

三、最新Python学习笔记

当我学到一定基础,有自己的理解能力的时候,会去阅读一些前辈整理的书籍或者手写的笔记资料,这些笔记详细记载了他们对一些技术点的理解,这些理解是比较独到,可以学到不一样的思路。

img

四、Python视频合集

观看全面零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。

img

五、实战案例

纸上得来终觉浅,要学会跟着视频一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。img

六、面试宝典

在这里插入图片描述

在这里插入图片描述

简历模板在这里插入图片描述

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里无偿获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在使用`tornado_mysql`的连接池时,可以使用以下代码来执行事务: ```python import tornado.ioloop import tornado.web import tornado.gen import tornado_mysql class MainHandler(tornado.web.RequestHandler): async def get(self): db = self.application.db async with db.pool.acquire() as conn: async with conn.cursor() as cur: try: await cur.execute("START TRANSACTION") await cur.execute("INSERT INTO table_name (column1, column2) VALUES (%s, %s)", (value1, value2)) await cur.execute("UPDATE table_name SET column3 = %s WHERE id = %s", (value3, id)) await cur.execute("COMMIT") self.write("Transaction completed successfully!") except: await cur.execute("ROLLBACK") self.write("Transaction failed") class Application(tornado.web.Application): def __init__(self): handlers = [ (r"/", MainHandler), ] self.db = tornado_mysql.Pool( dict(host='localhost', port=3306, user='root', passwd='password', db='database_name'), max_size=10, autocommit=True ) super(Application, self).__init__(handlers) if __name__ == "__main__": app = Application() app.listen(8888) tornado.ioloop.IOLoop.current().start() ``` 在上述代码中,我们首先创建了一个`Pool`对象,它包含了数据库的连接参数和连接池的最大连接数。然后,在我们的请求处理程序中,我们通过`pool.acquire()`方法获取一个连接。我们使用`async with`来确保在完成事务后自动释放该连接。 在使用的连接上创建一个`cursor`来执行事务中的SQL语句。在使用`try/except`块执行SQL语句时,如果任何一个语句失败,我们将立即回滚整个事务。如果所有语句都成功执行,则提交事务。 总之,使用`tornado_mysql`的连接池和事务非常简单,只需要在您的代码中添加一些额外的异步语句即可。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值