携带状态的闭包

闭包

在 Python 中,函数也是一个对象。因此,我们在定义函数时,可以再嵌套定义一个函数,并将该嵌套函数返回,比如:

1
2
3
4
5
6
from math import pow
def make_pow(n):
def inner_func(x): # 嵌套定义了 inner_func
return pow(x, n) # 注意这里引用了外部函数的 n
return inner_func # 返回 inner_func

上面的代码中,函数 make_pow 里面又定义了一个内部函数 inner_func,然后将该函数返回。因此,我们可以使用 make_pow 来生成另一个函数:

1
2
3
4
5
>>> pow2 = make_pow(2) # pow2 是一个函数,参数 2 是一个自由变量
>>> pow2
<function inner_func at 0x10271faa0>
>>> pow2(6)
36.0

阅读全文 »

Flask Web 开发笔记

书籍地址

head-first-flask

Flask 简介

Python 中有许多 Web 开发框架,比如 DjangoFlaskTornadoBottleweb.py 等,其中,Django 可以说是一个全能型(all in one)的框架,自带管理后台;而 Flask 则是一个非常轻量级的框架,提供了搭建 Web 服务的必要组件,如果你不喜欢自带的组件,由于 Flask 良好的扩展性,你也可以使用其他开源的 Flask 扩展插件,甚至可以自己写一个,让喜欢折腾的开发者一展身手;Tornado 则主打异步处理,高并发,这也是它的一个显著特点。

第一次接触到 Flask 时被它的简洁感动了,几行代码就可以快速搭建出一个简单的 Web 服务,于是就开心地踏上了 Flask 的学习之路,慢慢地就学习到了诸如 Jinja2 模板引擎,路由,视图,静态文件和蓝图等。Flask 非常小,源码文件包括注释在内,总共才 6000 多行,当你能熟练使用 Flask 的各个模块时,相信你也可以读懂它的所有源码。

阅读全文 »

陌生的 metaclass

元类

Python 中的元类(metaclass)是一个深度魔法,平时我们可能比较少接触到元类,本文将通过一些简单的例子来理解这个魔法。

类也是对象

在 Python 中,一切皆对象。字符串,列表,字典,函数是对象,类也是一个对象,因此你可以:

  • 把类赋值给一个变量
  • 把类作为函数参数进行传递
  • 把类作为函数的返回值
  • 在运行时动态地创建类

看一个简单的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Foo(object):
foo = True
class Bar(object):
bar = True
def echo(cls):
print cls
def select(name):
if name == 'foo':
return Foo # 返回值是一个类
if name == 'bar':
return Bar
>>> echo(Foo) # 把类作为参数传递给函数 echo
<class '__main__.Foo'>
>>> cls = select('foo') # 函数 select 的返回值是一个类,把它赋给变量 cls
>>> cls
__main__.Foo

阅读全文 »

你不知道的 super

super() 的入门使用

在类的继承中,如果重定义某个方法,该方法会覆盖父类的同名方法,但有时,我们希望能同时实现父类的功能,这时,我们就需要调用父类的方法了,可通过使用 super 来实现,比如:

1
2
3
4
5
6
7
8
9
10
class Animal(object):
def __init__(self, name):
self.name = name
def greet(self):
print 'Hello, I am %s.' % self.name
class Dog(Animal):
def greet(self):
super(Dog, self).greet() # Python3 可使用 super().greet()
print 'WangWang...'

在上面,Animal 是父类,Dog 是子类,我们在 Dog 类重定义了 greet 方法,为了能同时实现父类的功能,我们又调用了父类的方法,看下面的使用:

1
2
3
4
>>> dog = Dog('dog')
>>> dog.greet()
Hello, I am dog.
WangWang..

阅读全文 »

Flask 插件系列 - Flask-MongoEngine

简介

MongoDB 是一个文档型数据库,是 NoSQL (not only SQL) 的一种,具有灵活、易扩展等诸多优点,受到许多开发者的青睐。MongoEngine 是一个用来操作 MongoDB 的 ORM 框架,如果你不知道什么是 ORM,可以参考 Flask-SQLAlchemy 一节。在 Flask 中,我们可以直接使用 MongoEngine,也可使用 Flask-MongoEngine ,它使得在 Flask 中使用 MongoEngine 变得更加简单。

安装

使用 pip 安装,如下:

1
$ pip install flask-mongoengine

阅读全文 »

Flask 插件系列 - Flask-SQLAlchemy

简介

Web 开发中,一个重要的组成部分便是数据库了。Web 程序中最常用的莫过于关系型数据库了,也称 SQL 数据库。另外,文档数据库(如 mongodb)、键值对数据库(如 redis)近几年也逐渐在 web 开发中流行起来,我们习惯把这两种数据库称为 NoSQL 数据库。

大多数的关系型数据库引擎(比如 MySQL、Postgres 和 SQLite)都有对应的 Python 包。在这里,我们不直接使用这些数据库引擎提供的 Python 包,而是使用对象关系映射(Object-Relational Mapper, ORM)框架,它将低层的数据库操作指令抽象成高层的面向对象操作。也就是说,如果我们直接使用数据库引擎,我们就要写 SQL 操作语句,但是,如果我们使用了 ORM 框架,我们对诸如表、文档此类的数据库实体就可以简化成对 Python 对象的操作。

Python 中最广泛使用的 ORM 框架是 SQLAlchemy,它是一个很强大的关系型数据库框架,不仅支持高层的 ORM,也支持使用低层的 SQL 操作,另外,它也支持多种数据库引擎,如 MySQL、Postgres 和 SQLite 等。

阅读全文 »

Flask 插件系列 - Flask-Mail

简介

给用户发送邮件是 Web 应用中最常见的任务之一,比如用户注册,找回密码等。Python 内置了一个 smtplib 的模块,可以用来发送邮件,这里我们使用 Flask-Mail,是因为它可以和 Flask 集成,让我们更方便地实现此功能。

安装

使用 pip 安装:

1
$ pip install Flask-Mail

或下载源码安装:

1
2
3
$ git clone https://github.com/mattupstate/flask-mail.git
$ cd flask-mail
$ python setup.py install

阅读全文 »

Flask 系列 - 工厂方法

工厂方法

在开始学 Flask 的时候,我们都是直接通过app=Flask(__name__)来创建一个app实例的。这样做没什么问题,但如果我们想为每个实例分配不同的配置,比如有测试环境的配置,开发环境的配置和生产环境的配置等,这时就比较麻烦了。

有什么办法呢?

其实我们可以通过调用一个函数来返回一个应用实例,比如下面的方法:

1
2
3
4
5
6
7
8
9
10
def create_app(config_filename):
app = Flask(__name__)
app.config.from_pyfile(config_filename)
from yourapplication.views.admin import admin
from yourapplication.views.user import user
app.register_blueprint(admin)
app.register_blueprint(user)
return app

上面的create_app函数就是一个工厂方法,我们将创建应用程序实例的工作交给了它来完成,我们以后就可以通过传入不同的配置名,以此批量生产app

阅读全文 »

Flask 系列 - 消息闪现

消息闪现

Flask 提供了消息闪现的功能,以使我们的应用可以向用户反馈信息。比如,当用户登录失败了,我们会提醒用户名错误或者密码错误。

在 Flask 中使用消息闪现很简单。下面我们以上一篇的例子进行说明。完整的代码在这里

首先,让我们看一下book.py的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# -*- coding: utf-8 -*-
from flask import Blueprint, url_for, render_template, request, flash, redirect
book_bp = Blueprint(
'book',
__name__,
template_folder='../templates',
)
books = ['The Name of the Rose', 'The Historian', 'Rebecca']
@book_bp.route('/', methods=['GET'])
def index():
return '<h1>Hello World!</h1>'
@book_bp.route('/book', methods=['GET', 'POST'])
def handle_book():
_form = request.form
if request.method == 'POST':
title = _form["title"]
books.append(title)
flash("add book successfully!") # 使用 flash 反馈消息
return redirect(url_for('book.handle_book'))
return render_template(
'book.html',
books=books
)

阅读全文 »

Flask 系列 - 蓝图

蓝图

在开始学 Flask 的时候,我们习惯把代码写在单一的文件里面,虽然看起来很方便,但也只是供学习的时候用用而已,真正在一个实际项目中,是不应该这样做的,为什么呢?

我们还是从 hello world 开始讲起,新建一个脚本文件,比如 hello.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ cat hello.py
# -*- coding: utf-8 -*-
from flask import Flask
app = Flask(__name__)
@app.route("/")
def index():
return "Hello World!"
if __name__ == "__main__":
app.run(host='127.0.0.1', port=5200, debug=True)

运行该脚本,在浏览器输入链接 http://localhost:5200/,可以看到 Hello World! 的字样。

阅读全文 »