Dust8 的博客

读书百遍其义自见

0%

sys.path是什么

[sys.path](https://docs.python.org/3/library/sys.html#sys.path) 是一个字符串列表,用来指定搜索模块的路径.每次调用解析器都会初始化它,所以不用担心改变它会污染环境.

sphinx里面的用法

sphinx 里使用 autodoc 或者 sphinx-apidoc, 必须要引入包.
一种方法就是先安装包,另外一种就是在 conf.py 文件里面写入下面的内容:

import os
import sys
sys.path.insert(0, os.path.abspath('..'))

这样就可以引入包了,而退出之后又不会影响环境.
这里为啥是 ..,因为我的项目目录是这样的:

.
├── bencoding
│   ├── __init__.py
│   ├── decoder.py
│   ├── encoder.py
│   └── tokens.py
├── docs
│   ├── Makefile
│   ├── conf.py
│   ├── index.rst
│   ├── install.rst
│   ├── make.bat
│   ├── module.rst
│   └── quickstart.rst
├── setup.py
└── tests
    ├── __init__.py
    ├── context.py
    ├── test_decoder.py
    └── test_encoder.py

单元测试的用法

在 《The Hitchhiker’s Guide to Python》里的 Test-Suite 有提到怎么优雅的引入包.
先新建文件 tests/context.py :

import os
import sys
sys.path.insert(0, os.path.abspath('..'))

import bencoding # bencoding 就是你的包

然后就可以在测试文件里引入

from .context import bencoding

如果你的包层级太多可以这样

from .context import bencoding
from bencoding.decoder import Decoder

这样就完美了.

起因

今天看到董伟明的《python web 开发实战》里面的 善用for...else语句 才发现原来还有这种用法.
我一直不知道 for 后面还有语句.他的例子是寻找符合条件的序列的索引值:

常见方法
def find(seq, target):
    found = False
    for i, value in enumerate(seq):
        if value == target:
            found = True
            break
    if not found:
        return -1
    return i

更好的方法
def find(seq, target):
    for i, value in enumerate(seq):
        if value == target:
            break
    else:
        return -1
    return i

查看官方文档

Tutorial – for-statements

for Statements
tutorial 里面的控制语句看起,才发现用了这么久的 python, 才用了最简单的用法–iter.

>>> # Measure some strings:
... words = ['cat', 'window', 'defenestrate']
>>> for w in words:
...     print(w, len(w))
...
cat 3
window 6
defenestrate 12

这个用法就是我们最经常见到的用法了,在来看下另外一个魔法用法:

>>> for w in words[:]:  # Loop over a slice copy of the entire list.
...     if len(w) > 6:
...         words.insert(0, w)
...
>>> words
['defenestrate', 'cat', 'window', 'defenestrate']

这里利用了切片的魔法 words[:],它把 words 复制了一下, 所以 for 枚举的是words
的副本, 然后才可以在子句里面操作 words.这里又学到了一招,但是还是没有发现有for...else
的用法.

Language Reference – The for statement

The for statement
在这里我们可以看到 for 语句的 BNF:

for_stmt ::=  "for" target_list "in" expression_list ":" suite
          ["else" ":" suite]

for 语句是用来枚举序列(字符串,元组,列表)和可枚举对象的元素.当元素耗尽,如果有else子句,就会执行 else 子句里面的语句.如果在第一个 suite 里面执行了 break 语句就不会在执行 else 子句.

总结

  • 官方文档才是最全的书.看过不少书和文章,这个 for...else 只见过这一次提及到.
  • 学精知识就需要追根究底.比如要学精python,就需要深入它的本身,而不仅仅只学它的用法.就像前面的 Tutorial 文档就是它的用法, 而 Language Reference 文档才是它的本身.

本博客用的是 github page, 使用了自定义域名 dust8.com.
以前使用的是 A 记录, github 总是发送警告邮件说推荐使用 CNAME 记录,
所以就决定改为 CNAME 记录, 一改就掉坑里了.先剧透一下,所有的配置都没有问题,都是 chrome 惹的祸.

经验主义有它的优点,也有很明显的缺点.打个比方你以前天天吃肉,别人就认为你今天不吃素,
虽然你今天吃肉的概率非常大,但是也不能排除你今天突然想吃素.说到这里就想起腾讯的lol游戏,
说我使用加速外挂把我封了,然而我并没有使用外挂,申诉也没人理,3天后申诉系统回给你一个空信息.
在申诉中发现它有提到使用了行为检测系统,但是点击查询却全是说系统繁忙,根本就不提供你有哪些行为.
很恼火,觉得就像它认为人都是2条腿走路,如果不是2条腿走路就不是人一样,把残疾人,狼人和猿人排除了.
如果你以前的战绩差,突然就厉害了,它就说你是挂,完全没想到是不是对手太菜,你今天超常发挥或者你提升很快.

检查配置

按照 github 官网的帮助文档一步一步来配置,配置好后要等一段时间才有效.
等到晚上还是打不开网站,就按照帮助文档测试下

dig www.dust8.com +nostats +nocomments +nocmd  

; <<>> DiG 9.8.3-P1 <<>> www.dust8.com +nostats +nocomments +nocmd
;; global options: +cmd
;www.dust8.com.            IN    A
www.dust8.com.        2109    IN    CNAME    dust8.github.io.
dust8.github.io.    2110    IN    CNAME    github.map.fastly.net.
github.map.fastly.net.    13    IN    A    151.101.16.133
fastly.net.        6663    IN    NS    ns3.fastly.net.
fastly.net.        6663    IN    NS    ns4.fastly.net.
fastly.net.        6663    IN    NS    ns1.fastly.net.
fastly.net.        6663    IN    NS    ns2.fastly.net.

可以看到已经起作用了.还是打不开网页.就清除电脑dns缓存,重启电脑,重启路由器,都没效,其实这些都不需要的,
因为上面那个命令显示dns已经解析成功了.后来还清除浏览器dns,一样无效.

换浏览器

换成 safari 也是一样说 dust8.com’s server DNS address could not be found..
这句话很迷惑人,一直以为是 dns 有问题, 可以说是它的原因,也可以说不是它的原因.
换成手机浏览器夸克居然可以打开网站,那就可以肯定是浏览器问题,因为手机和电脑用的是同一个 wifi.

这里也有疑点,为什么 safari chrome 都不可以,后来才想起来 safari 导入了 chrome 的数据.
safari 清除数据后果然可以打开 www.dust8.com, 同理清除 chrome 数据后也可以打开了.
同时也注意到地址栏里面的网址是 www.dust8.com 而不是打不开时的 dust8.com.

结论

结果已经很明了了, chrome 会自动记录浏览习惯来方便用户,但有时又会带来不便.
以前的域名解析是同时解析 dust8.comwww.dust8.com ,改了之后只解析www.dust8.com,
而浏览器根据以前的浏览习惯强制把 www.dust8.com 转到 dust8.com,
dust8.com 却没有设置解析, 所以才提示 dust8.com’s server DNS address could not be found.

以前调低画质就可以比较流畅的玩 csgo, 后来更新使用 64 位的客户端就卡得不要不要的.要想流畅玩必须要注意以下几点:

输入法

输入法必须调到英文状态,不能是中文的.

调低画质

这个自己搜索就可以了,网上比较多.

使用调节电脑风扇软件

默认风扇转速比较慢,当电脑温度比较高时,自动降频,所以会卡.
使用 smcFanControl 软件来调高风扇转速.

brew install smcFanControl

调教鼠标

安装 MouseFixer 来保持鼠标和游戏一致.

下载地址

smcFanControl
MouseFixer

以前只要设置 app.run(debug=True) 就可以重载模版文件了.
flask 0.11 改动了设置, 这样只能重载 python 文件, 不能连模版文件一起重载.
要想模版文件一起重载需要设置 TEMPLATES_AUTO_RELOAD 这个配置(Flask Changelog).
例如:

app.config['TEMPLATES_AUTO_RELOAD'] = True

但是使用后还发现如果是 include 进来的模版改动后还是不能重载.
必须要这样设置才可以:

app.config['DEBUG'] = True

所以推荐使用配置文件的形式引入配置:

config.py
DEBUG = True
TEMPLATES_AUTO_RELOADT = True


app.py
app.config.from_pyfile('config.py')
app.run()

还有就是静态文件被缓存了,例如 css, js 这些文件改动后,刷新网页也看不到改动后的效果.
可以在文件名后面加入随机字符, 可以看看 static url cache buster.

@app.context_processor
def override_url_for():
    return dict(url_for=dated_url_for)

def dated_url_for(endpoint, **values):
    if endpoint == 'static':
        filename = values.get('filename', None)
        if filename:
            file_path = os.path.join(app.root_path,
                                     endpoint, filename)
            values['q'] = int(os.stat(file_path).st_mtime)
    return url_for(endpoint, **values)