一
记得刚开始工作的时候,老大给我们上 C++ 基础课,告诉我们字符串字面量可以换行(如下代码),感觉真是如梦如幻。
- #include <stdio.h>
- int main(int argc, char** argv)
- {
- char* w = "hello"
- " "
- "world."
- ;
- printf("%s", w);
- return 0;
- }
- hello world.
- >>> t = ('hello'
- ... ' '
- ... 'world')
- >>> t
- 'hello world'
二
在写 absolute32(见:http://blog.csdn.net/lanphaday/article/details/6762023)的测试代码的时候,为了让测试代码兼容 Python2.x/3.x 两大版本,引入了一砣丑陋的代码:
- if sys.version < '3':
- exec("chinese = unicode('赖勇浩', 'utf-8')")
- else:
- exec("chinese = '赖勇浩'")
- chinese = '赖勇浩'
- chinese = u'赖勇浩'
- >>> x = '中国'
- >>> x
- '\xe4\xb8\xad\xe5\x9b\xbd'
- >>> from __future__ import unicode_literals
- >>> y = '中国'
- >>> y
- u'\u4e2d\u56fd'
这样,我那砣丑代码也可以美化掉啦!
三
先来看两句代码- record = cursor.execute('select * from tbl where id = 123456').fecth_all()[0]
- msg = struct.unpack('!I', buff)[0]
- record, = cursor.execute('select * from tbl where id = 123456').fecth_all()
- msg, = struct.unpack('!I', buff)
这种写法,据我以前的同事测试,比使用 [0] 要慢上 20% 左右。如果你很在意,建议使用之前的写法。另外,两种写法到底哪个更漂亮、更 Pythonic,也没有定论,但我喜欢后者。
四
用 ConfigPaser 是解释 ini 文件的利器,因为有这么好用库,所以我写的项目基本上都是用 ini 文件来配置的。ConfigParser 支持 DEFAULT 节,写在 DEFAULT 节中的配置项可以作为实参替换后续的引用,比如在我之前提过的“ 棋牌OnWeb”项目中,我们使用这样的配置文件:- [DEFAULT]
- base_path= /home/qipai-v1/src/server
- [policy]
- switch = on
- port = 18843
- path = %(base_path)s/hall/config/flashpolicy.xml
不过在这里要讲的不是这个技巧。如果你有留意到 ConfigParser.ConfigParser 类的那个 defaults 参数,那就是真正的我要讲的东西了。defaults 参数可以补充 ini 文件中 DEFAULT 文件的不足,能够运行时再决定变量的实参。比如在“ 棋牌OnWeb”项目中,所有的游戏进程都由一个叫 desk 的程序来服务的,它通过命令行传入的参数加载不同的插件实现不同的业务逻辑。比如 desk --game-name=doudizhu 可以运行一个斗地主的服务,desk --game-name=xiangqi 则是中国象棋。显然,为了方便通过日志分析错误,有必要把日志按游戏、房间和桌子分离开来,比如 xiangqi-1-10.log 表示象棋游戏的房间1桌子10的进程的日志,这时候如果使用内置的 logging 模块来记录日志,我们可以这样配置它:
- [handler_game]
- class=handlers.TimedRotatingFileHandler
- formatter=comm
- args=('log/%(game_name)s-%(rid)d-%(did)d.log', 'midnight', 1, 30)
- logging.config.fileConfig(conf, defaults = dict(game_name = game_name, rid = rid, did = did))