Python datetime 处理时区信息

Python 常用日期处理 -- 内置模块 datetime 探讨了 Python  如何使用 datetime, 如果是一个跨时区的应用(Web 应用都是),就不能只存储一个时间而不带时区,如此,全球用户将会看到一个相同的时间字符串,白天黑夜就错乱了。比说用户信息的更新时间存储为 2020-07-07 13:46:08, 上海的用户和芝加哥的用户看到的是同一个时间字符串,实质上却相差好多个小时。

我们可以这么做,在服务端只存储一个 Timestamp 长整型值或 UTC 时间,Timestamp 是无关乎时区的,它总是相对于一个 UTC 时间的偏移值; 然后由客户端根据本地时区来显示当地时间。不过在服务端存储为 Timestamp 或 UTC 可读性就不强了,打开文件看到 Timestamp 整形值,大脑是无法直接转换为日期,UTC 时间略好一些。

另一种做法可在服务端存储为开发者便于理解的带时区的时间,如 2020-07-07T13:46:08.342+08:00, 客户获得该时间,因为带有时区信息也就能转换为客户端本地时间。

客户端请求时还可以把本地的时区信息传送给服务端,由服务端转换为相应的本地时间发送给客户端,但 HTTP 头信息默认不带时区信息,客户端必须主动发送它。 阅读全文 >>

Flask, Vue.js 中集成 Bootstrap/BootstrapVue

紧接上一篇 Flask 和 Vue.js 开发及整合部署实例,来体验一下它们与 Bootstrap/BootstrapVue 的集成。漂亮的网站少不得一个好的 CSS 框架,现在有许许多的 CSS 框架可选,纯 CSS 的, 轻量级的, 含 JS 的 CSS 框架,如 Pure, Bulma, Spectre, 国产的 Element 等。而我总觉得 Bootstrap 更是五臟俱全,像 Element 专为 Vue.js 打造的一样,Bootstrap 也有 BootstrpVue 那样一个结晶品。

本文准确的内容应该是关于 Vue.js 与 Bootstrap/BootstrapVue 的话题,与 Flask 没什么事,不过这里呢,还是强拉上 Flask, 由 Flask 的 API 来产生一些数据。

同样是阅读 Flask和Vue.js构建全栈单页面web应用【通过Flask开发RESTful API】的一个实践品。本篇基于 Flask 和 Vue.js 开发及整合部署实例 中的步骤建立的项目 flask-vue-app,方便起见,用了一个新项目名称 flask-vue-bootstrap。记得我们为 Flask 和 Vue.js 分别建立了 backend  和 frontend 两个子项目。 阅读全文 >>

Flask 和 Vue.js 开发及整合部署实例

想做些简单的 Web 工具,首先想到的是 Flask + Vue.js, 当然可以完全用 Flask 自己的页面模板 Jinja2, 但一个网站项目不能享受到像 Vue.js, React 类似框架的灵活性真是太可惜了。于是 Flask 只专注于 API, 页面逻辑全用 Vue.js 的组合就成了我的首选,Flask 方面还能进一步选择 FlaskRESTful 框架。还需做得更漂亮的话,CSS 框架可选择 Bootstrap 或与 Vue 紧密集成的 BootstrapVue, 这是后话。

本文主要参考 Flask和Vue.js构建全栈单页面web应用【通过Flask开发RESTful API】的前部分,英文原文在这里 Developing a Single Page App with Flask and Vue.js

开发过程中我们可以保持 Flask 和  Vue.js 为单独的两个项目,并启动各自的服务,比如 Flask 是 http://localhost:5000, Vue.js 项目通过 npm run serve 启动在 http://localhost:8080,借助于 node js 的功能,修改 Vue.js 项目的内容能够自动刷新网页。要是开发中把静态文件全放在  Flask 项目中,那么任何对静态文件的修改都必须重启 Flask  服务。虽然 Debug 模式启动的 Flask 在看到它的目录中有任何修改时也能自动重启,但对静态文件的修改重启 Flask 没这个必要性。 

但部署时需进一步整合,最终只需要启动 Flask  服务,而无须两个,方便部署。如果是以 Docker 容器的方式发布,使用 docker-compose 来编排两个容器来发布也还算不错。更专业的部署方式应该是 Vue.js 的静态内容放到专门的 Web 服务器,如  Apache/Nginx 中,Flask 也通过 wsgi 与 Web 服务器集成起来。 阅读全文 >>

Python 列表的排序 - sort/sorted

Python 集合的遍历,推导及 filter/map/reduce 操作 中讲了对集合的 filter, map 和 reduce 操作,那还有 sort 排序呢?像 Java 一样,Python  也提供了 sort() 和 sorted() 方法。

sort() 是 list 的实例方法, sorted() 是一个内置函数。Python 中也是只有 list 才有顺序。

list.sort() 方法

查看 Python 3 中的 list.sort() 方法(help(list.sort))

Help on method_descriptor:

sort(self, /, *, key=None, reverse=False)
Stable sort *IN PLACE*.

Python 的 list.sort() 方法和 Java List.sort() 方法一样的,都是 IN PLACE 排序,没有返回值。实际看下各种排序场景 阅读全文 >>

创建 Python 的 list, set, tuple 和 dict

本文主要探讨一下在 Python 各种创建 list, set, tuple 和 dictionary 的方式。首先看

最常用的创建方式

以上相当于是针对右边的值调用了相应的构造函数,如 list([1, 2]), set({1, 2}), tupe((1, 2)), dict({'k1': 1, 'k2': 2})

创建 set 和 dictionary 都是用大括号 {}, 对于 tuple 如果是单个元素时,要附加一个逗号

如果省略逗号,会怎样呢? 阅读全文 >>

理解 Python 类的变量,方法与属性

熟悉了传统的 C++/Java 类定义的风格,来感受一下 Python 是如何定义类的。本篇是阅读 《The Quick Python Book》第二版关于类定义的笔记,由原书内容进一步引申,不过是依照本人的思考顺序来组织的。在理解 Python 类定义的同时头脑中应该闪现出 JavaScript/Java 如何定义类的情景。

最简单的类定义

class MyClass:
    pass

由于 class MyClass 后面要有个冒号,而冒号后总得有点东西才能表示该类定义结束了,于是放个 pass 当占位符。Python 也像 Java 一样,有一个根类,叫做 object,例如上面的定义

我们能看到它隐式的基类是 object, 而不用显式的声明为 class MyClass(object)。看到 __bases__ 属性是一个 Tuple, 意识到  Python 是支持多重继承的。 阅读全文 >>

Python print 立即打印内容到重定向的文件

看到本文标题也许要奇怪了,Python 的 print 难道不是也上可以看到结果的吗?在 Python shell 下只要 

>> print('Hello world!')
Hello world!

不就立马能看到控制台输出的 "Hello world!" 吗。或者是一个 Python 脚本文件 hello.py

import time

for i in range(3):
    print('Hello {}'.format(i))
    time.sleep(3)

然后执行 python hello.py 的话,我们也同样能看到在控制台下在预定的每 3 秒输出一行

Hello 0
Hello 1
Hello 2

但执行下面的命令试图重定向输出到文件时的效果就不一样了 阅读全文 >>

体验一下 Python 3.8 带来的主要新特性

学习理解一个软件非常好的方法就是跟随每一个版本演进的新特性,好比一个人被别人看着长大的,知子莫若父。因此每个版本的 Changelogs 或 What's New 是非常值得一读的,见 What's New In Python 3.8。因为接触 Python 比较晚,没能即时的重前往后的看过 Python 各版本的新特性,于是采用倒叙的方式来看 Python 的演进也不错。

在正式进入 Python 3.8 新特性前,先来看 Python 3.8 的安装和以及介绍一个非常棒的 Python 命令行解析器 bpython 作为 python 命令,ipython, idle 的替代品。

Python 3.8 各平台的安装包可在 https://www.python.org/downloads/release/python-380/ 找到。比如 Mac OS X 下可下载 https://www.python.org/ftp/python/3.8.0/python-3.8.0-macosx10.9.pkg,然后执行安装。安装完后,我机器上的 /usr/local/bin/python3 就指向到了 Python 3.8, 要用 Python 3.7 的话命令是 python3.7; pip3 却仍然是老版本的。

bpython 的安装要用相应版本的  pip install bpython, 如 /Library/Frameworks/Python.framework/Versions/3.8/bin/pip3 install bpython, 或者创建的虚拟环境中安装, python -m venv .venv; source .venv/bin/activate; pip install bpython。安装后启动  bpython 进入一个更智能的 Python 命令解析器。py

下面正式了解 Python 3.8 的主要新特性 阅读全文 >>

Python 执行系统命令 - subprocess 模块的使用

Python 可信手拈来写系统脚本,那么在 Python 中调用系统命令应该会比较便捷。所以本文来看看 Python 有几种方式调用系统命令,以及与回味一下其他几种脚本语言的类似操作。简单说来,Python 执行系统命令的方式有四种方式,即

  1. os.system(cmd) (建议用 subprocess 模块)
  2. os.popen(cmd) (Python 3 中还能用,但不推荐使用了)
  3. commands 模块(在 Python 3 中已移除了该模块,基本是不必去了解它)
  4. subprocess 模块(总是上面的矛头全指向它的,重点)

os.system(cmd)

启动一个子进程来执行系统命令,可以获得标准输入,不能获到命令输出, 但可以得到一个状态码 阅读全文 >>

Python 函数声明先后顺序的问题

在 Python 中如果把函数定义写在调用的下方可能会出错,例如下面的代码

foo()

def foo():
    print("hello")

执行时会报出错误

NameError: name 'foo' is not defined

这时候要把 foo() 调用代码放到该函数的声明后面

def foo():
    print("hello")

foo()

这样执行就一切正常了。这仿佛像是 C 语言中的函数调用需要提前声明一般,例如在 C 语言中要调用后头的定义的函数要写成 阅读全文 >>