zzxworld

Python Sanic 框架体验总结

过年前发了一篇文章《Python Web 开发框架 - Sanic 初探》,提到我准备抛弃 PHP 的 Laravel 框架,并开始尝试使用 Python 的 Sanic 框架来完成项目。目前半个多月过去了,我准备分享一点实际使用后的体验和想法。

从零开始

用来练手的是我的一个实验项目:「BlogFinder」。一个针对个人独立博客的聚合类网站。功能和页面都算是比较简单。之前是用 Laravel 写的,这次我想看看用 Sanic 来写感觉如何。

默认的 Sanic 连 HTML 模板都不支持,所以需要根据情况,通过 pip 命令来引入各种 Python 扩展。比如我就引入了下面这些:

  • sanic-session:Session 功能支持。
  • Jinja2:HTML 模板功能支持。
  • orator:数据库模型功能。因为习惯了 Rails 和 Laravel 这种 Active Record 模式的数据模型,所以选择了这样一个在 Python 语言下显的比较偏门的数据库扩展包。
  • validators:提供数据验证功能。
  • argparse:提供自定义命令的入口包装和参数解析功能。
  • beautifulsoup4:HTML 解析功能。
  • feedparser:RSS 数据解析功能。
  • Pillow:图片处理功能。
  • python-dateutil:日期解析功能。

Sanic 作为一个「微」框架,以上这些都需要自己集成到项目中来。比如 Orator 数据模型,我就需要创建一个初始化数据库连接实例的函数:

from orator import DatabaseManager

def db_init():
    """
    初始化数据库实例
    """
    config = {
            'default': 'app',
            'app': {
                'driver': 'sqlite',
                'database': 'database/app.sqlite'
                }
            }  # 演示用,实际项目放置到专门的配置文件

    return DatabaseManager(config)

包括渲染 HTML 模板的 Jinja2

from jinja2 import Environment, FileSystemLoader, select_autoescape

def view_init():
    """
    初始化模板视图实例
    """
    return Environment(
            loader=FileSystemLoader('views'),
            autoescape=select_autoescape(['html', 'xml']))

然后在项目的入口文件中创建完 Sanic 对象后绑定它们到环境变量 ctx 上:

from app.ext import db_init, view_init

app = Sanic(__name__)
app.ctx.db = db_init()
app.ctx.view = view_init()

这样就可以在业务功能中调用 app.ctx 下的实例对象来应用相关的功能了。

看起来好像也不复杂。但在使用 Sanic 开发项目时,如果没有相关实践和代码的积累,前期会充斥着大量这种基础性的建设工作。比如文件目录安排,扩展包调用方式,功能模块的开发模式和安排等。这感觉像是自己在重新设计一个框架,而不是在写业务代码。所以在这十多天的时间里,我花在业务代码上的时间其实并不多,基本都是在不断调整和优化一些基础结构以及功能。以便让自己在业务代码部分用的更加舒服。

值得使用吗?

我想这个问题要看使用环境。对我来说,目前还不值得使用。

拿练手的这个项目来说,如果换成 Laravel,即便是前后端全部重写,最多也就 3 天时间。我用 Sanic 大概花了十多天。从产出上来衡量,这个效率有点难以接受。重点是目前完成的代码和结构依然还不太令我满意,感觉像是拼凑了一堆代码,能够运行起来而已。

另外一些功能扩展包也让人不太放心。比如上面提到的数据库模型包:Orator。最后一次代码更新还是在 2 年前。还有类似 Sanic-session 这样的扩展,版本号还停留在 0.* 这样的阶段。这些情况也就意味着如果我要用 Sanic,后期还要继续投入大量时间到基础结构上来。作为一个还在温饱线上挣扎的自由职业者,投入大量时间研究这些有点得不偿失。

其次,在项目上线部署环节,由于语言特性,Python 无法像 PHP 那样做到资源最大化利用。什么意思呢?比如我现在手头有好几个小项目。如果用 Sanic 来写,上线部署后,即便没人访问,项目启动后依然是要占用相应的内存资源。而 PHP 却可以使用一个 FPM 服务支撑多个项目。所以我青睐于继续使用 PHP。

最后

我早已厌倦了 PHP,但每次想要抛弃它时,一番尝试下来又不得不接受现实。在 Web 开发领域,它依然还是具有一些不可替代的闪光点。特别是 Laravel 这种类似 Rails 的开发框架,整合了各种最佳实践,真正可以让你不用关注太多基础性的事情,把精力和时间都用到业务功能实现上来。