Python WebDev
2017-01-30
示例
from werkzeug.wrappers import Request, Response
from werkzeug.routing import Map, Rule
class Application:
def __init__(self):
self.url_map = Map([
Rule('/', endpoint='hello')
])
def hello(self, request):
text = 'Hello, World!'
response = Response(text, content_type='text/plain')
return response
@Request.application
def __call__(self, request):
adapter = self.url_map.bind_to_environ(request.environ)
endpoint, values = adapter.match()
handler = getattr(self, endpoint)
return handler(request, **values)
if __name__ == '__main__':
from werkzeug.serving import run_simple
app = Application()
run_simple('localhost', 5000, app)
Werkzeug 与协程(async
/await
)
Werkzeug 1.x 开始已经提供了对协程的支持。
PS:WSGI 规范是基于同步的设计,没有较好的适配异步编程,所以后面一些更年轻的框架选择了 ASGI(Async Server Gateway Interface)。
PS:2014/03/01, WSGI
PS:2021/11/06, 体验 ASGI
import asyncio
from werkzeug.wrappers import Request, Response
from werkzeug.routing import Map, Rule
class Application:
def __init__(self):
self.url_map = Map([
Rule('/', endpoint='hello')
])
async def hello(self, request):
text = 'Hello, World!'
response = Response(text, content_type='text/plain')
return response
@Request.application
async def __call__(self, request):
adapter = self.url_map.bind_to_environ(request.environ)
endpoint, values = adapter.match()
handler = getattr(self, endpoint)
response = await handler(request, **values)
return response
if __name__ == '__main__':
from werkzeug.serving import run_simple
app = Application()
run_simple('localhost', 5000, app)
附:版本历史
版本 |
时间 |
2.3.4 |
May 9, 2023 |
2.3.3 |
May 1, 2023 |
2.3.2 |
Apr 29, 2023 |
2.3.1 |
Apr 27, 2023 |
2.3.0 |
Apr 26, 2023 |
2.2.3 |
Feb 15, 2023 |
2.2.2 |
Aug 9, 2022 |
2.2.1 |
Jul 28, 2022 |
2.2.0 |
Jul 24, 2022 |
2.1.2 |
Apr 29, 2022 |
2.1.1 |
Apr 2, 2022 |
2.1.0 |
Mar 29, 2022 |
2.0.3 |
Feb 8, 2022 |
2.0.2 |
Oct 6, 2021 |
2.0.1 |
May 18, 2021 |
2.0.0 |
May 12, 2021 |
1.0.1 |
Apr 1, 2020 |
1.0.0 |
Feb 7, 2020 |
0.16.1 |
Jan 27, 2020 |
0.16.0 |
Sep 19, 2019 |
0.15.6 |
Sep 5, 2019 |
0.15.5 |
Jul 17, 2019 |
0.15.4 |
May 15, 2019 |
0.15.3 |
May 15, 2019 |
0.15.2 |
Apr 3, 2019 |
0.15.1 |
Mar 22, 2019 |
0.15.0 |
Mar 20, 2019 |
0.14.1 |
Jan 1, 2018 |
0.14 |
Dec 31, 2017 |
0.13 |
Dec 8, 2017 |
0.12.2 |
May 16, 2017 |
0.12.1 |
Mar 16, 2017 |
0.12 |
Mar 10, 2017 |
0.11.15 |
Dec 31, 2016 |
0.11.14 |
Dec 31, 2016 |
0.11.13 |
Dec 27, 2016 |
0.11.12 |
Dec 26, 2016 |
0.11.11 |
Aug 31, 2016 |
0.11.10 |
May 24, 2016 |
0.11.9 |
Apr 25, 2016 |
0.11.8 |
Apr 15, 2016 |
0.11.7 |
Apr 15, 2016 |
0.11.6 |
Apr 14, 2016 |
0.11.5 |
Mar 23, 2016 |
0.11.4 |
Feb 15, 2016 |
0.11.3 |
Dec 20, 2015 |
0.11.2 |
Nov 12, 2015 |
0.11.1 |
Nov 10, 2015 |
0.11 |
Nov 8, 2015 |
0.10.4 |
Mar 26, 2015 |
0.10.3 |
Mar 26, 2015 |
0.10.2 |
Mar 26, 2015 |
0.10.1 |
Feb 4, 2015 |
0.10 |
Jan 30, 2015 |
0.9.6 |
Jun 7, 2014 |
0.9.5 |
Jun 7, 2014 |
0.9.4 |
Aug 26, 2013 |
0.9.3 |
Jul 25, 2013 |
0.9.2 |
Jul 18, 2013 |
0.9.1 |
Jun 14, 2013 |
0.9 |
Jun 13, 2013 |
0.8.3 |
Feb 5, 2012 |
0.8.2 |
Dec 16, 2011 |
0.8.1 |
Sep 30, 2011 |
0.8 |
Sep 30, 2011 |
0.7.2 |
Sep 30, 2011 |
0.7.1 |
Jul 26, 2011 |
0.7 |
Jul 24, 2011 |
0.6.2 |
Apr 24, 2010 |
0.6.1 |
Apr 13, 2010 |
0.6 |
Feb 19, 2010 |
0.5.1 |
Jul 10, 2009 |
0.5 |
Apr 25, 2009 |
0.4.1 |
Jan 11, 2009 |
0.4 |
Nov 23, 2008 |
0.3.1 |
Jun 24, 2008 |
0.3 |
Jun 15, 2008 |
0.2 |
Feb 14, 2008 |
0.1 |
Dec 10, 2007 |
Python WebDev
2017-01-30
这个组织下的每个项目单拿出来都是响当当的存在:
- Click — Beautiful, composable command line interface creation kit.
- Flask — a flexible and popular web development framework
- ItsDangerous — Safely pass trusted data to untrusted environments and back.
- Jinja — a full featured template engine for Python
- MarkupSafe — Safely add untrusted strings to HTML/XML markup.
- Quart — an async reimplementation of flask
- Werkzeug — The comprehensive WSGI web application library.
- Click 命令行工具
- Flask 轻量级 Web 框架
- ItsDangerous
- Jinja 知名模板库
- MackupSafe
- Quart
- Werkzeug Web 工具箱(WSGI),Flask 的底层
Python Unicode 字符编码
2016-06-22
源代码:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
print u'中国'
报错:
Traceback (most recent call last):
File "test.py", line 4, in <module>
print u'中国'
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)
Python
2016-05-16
-
bytes
按索引取值得到的是整数。
b'abc'[0]
97
-
str
转 bytes
只需要编码一下就行了。反过来就是解码一下。
s = '你好'
b = bytes(s, 'utf-8')
# b'\xe4\xbd\xa0\xe5\xa5\xbd'
assert b.decode('utf-8') == s
bytes('hello')
TypeError: string argument without an encoding
bytes('hello', 'ascii')
b'hello'
'hello'.encode()
b'hello'
bytes('hello', 'utf-16')
b'\xff\xfeh\x00e\x00l\x00l\x00o\x00'
bytes('hello', 'utf-32')
b'\xff\xfe\x00\x00h\x00\x00\x00e\x00\x00\x00l\x00\x00\x00l\x00\x00\x00o\x00\x00\x00'
-
bytes
和 int
列表的转换。
list(b'abc')
[97, 98, 99]
bytes([97, 98, 99])
b'abc'
bytes([256])
ValueError: bytes must be in range(0, 256)
# 大端序
(2008).to_bytes(length=4, byteorder='big', signed=False)
b'\x00\x00\x07\xd8'
# 小端序
(2008).to_bytes(length=4, byteorder='little', signed=False)
b'\xd8\x07\x00\x00'
struct.pack('<I', 2008)
b'\xd8\x07\x00\x00'
int.from_bytes(b'\x00\x00\x07\xd8', 'big')
2008
int.from_bytes(b'\xd8\x07\x00\x00', 'little')
2008
int.from_bytes(b'abc', 'little')
6513249
int.from_bytes(b'cba', 'big')
6513249
PS:2020/11/02, 字节顺序(大端序、小端序)
-
Python2 字符串
# python2
print(repr('你好'))
'\xc4\xe3\xba\xc3'
print('\xc4\xe3\xba\xc3')
你好
# python3
print('\xc4\xe3\xba\xc3')
'ÄãºÃ'
print('\xc4\xe3\xba\xc3'.encode('latin-1'))
b'\xc4\xe3\xba\xc3'
print('\xc4\xe3\xba\xc3'.encode('latin-1').decode('gbk'))
'你好'
Python
2016-02-03
import tempfile
import time
timestr = time.strftime("%Y%m%d%H%M%S")
临时文件
# tempfile.mktemp(suffix='', prefix='tmp', dir=None)
# tempfile.mkstemp(suffix=None, prefix=None, dir=None, text=False)
filepath_temp = tempfile.mktemp(suffix='.html', prefix='.cache_%s_' % timestr)
print(filepath_temp)
# /tmp/.cache_20210929205452_zlmi3pkf.html
filepath_temp = tempfile.mktemp(suffix='.html', prefix='.cache_%s_' % timestr,
dir='/opt/apps/markjour/tmp/')
print(filepath_temp)
# /opt/apps/markjour/tmp/.cache_20210929205452_mcr7nj3e.html
filepath_temp = tempfile.mkstemp(suffix='.html', prefix='.cache_%s_' % timestr, text=True)
mkstemp
和 mktemp
的区别:mkstemp
返回一个文件描述符,mktemp
返回一个文件路径。
mktemp
返回的路径理论上会被另一个进程使用,所以这是 UNSAFE 的,应该用 mkstemp
代替。
mktemp
从 Python 2.3 开始标记为 Deprecated,但是至今还是可以调用。
临时目录
# tempfile.mkdtemp(suffix=None, prefix=None, dir=None)
dirpath_temp = tempfile.mkdtemp()
print(dirpath_temp)
# /tmp/tmp1dj2cl0d
dirpath_temp = tempfile.mkdtemp(prefix='build_',
dir='/opt/apps/markjour/tmp/')
print(dirpath_temp)
# /opt/apps/markjour/tmp/build_9k5synh5
Python zip
2016-02-02
import zipfile
import os
zip_path = "/path/to/zip/file.zip"
extract_path = "/path/to/extract/directory"
if not os.path.exists(extract_path):
os.makedirs(extract_path)
with zipfile.ZipFile(zip_path, 'r') as fp:
# 直接解压
zip_ref.extractall(target_dir)
# 逐个解压
for filename in fp.namelist():
# 如果文件存在就先移除,避免 FileExistsError
extract_file_path = os.path.join(extract_path, filename)
if os.path.exists(extract_file_path):
# print("跳过解压缩文件:", filename)
# continue
os.remove(extract_file_path)
# 解压,会自动创建目录结构
fp.extract(filename, extract_path)
Python 字符编码
2016-01-23
关于 sys.setdefaultencoding
的一些问题。
Python
2016-01-21
.gitignore 常见的 *.py[cod]
。
参考 gitignore.io。
.py
.pyc
编译过后生成的字节码文件
.pyo
经过优化的字节码文件。Python2 时代常见,Python3 不再使用。现在是 .opt-1.pyc
, opt-2.pyc
PS:关于这个优化到底是做什么以后再好好研究。
.pyd
.pyi
Python Stub 文件,IDE 中为了提供更好的提示会带一些这样的文件,只是所有方法都是空的。
ps: 现在的 PyCharm 好像带的 stub 文件都是 py
后缀了。
.pyw
Windows 专供,py 文件由 python.exe 解析,pyw 文件由 pythonw.exe 执行
他们不同之处就是,python.exe 会导致一个命令行窗口的出现,而,pythonw.exe 不会,所以常用在 GUI 程序上。
.pth
自定义路径导入规则的文件,参考:.pth 文件和 site 模块
Python 压缩
2015-12-31
zlib
— Compression compatible with gzip
gzip
— Support for gzip files
bz2
— Support for bzip2 compression
lzma
— Compression using the LZMA algorithm
zipfile
— Work with ZIP archives
tarfile
— Read and write tar archive files
Python 编码规范
2015-12-01
pep8
是一个遵守 PEP8 编码规范的 Python 代码检测工具。