编写兼容Python2.6与Python3.0的程序

简而言之,在所有的py文件头加上:

# -*- coding:utf-8 -*-
from __future__ import print_function
from __future__ import unicode_literals
from __future__ import division
from __future__ import absolute_import
try:
    str=unicode
except NameError:
    pass

然后按照py3k的方式写程序。对于某些被重命令的库要处理一下。比如

try:
    import xmlrpclib as xrc
except ImportError:
    import xmlrpc.client as xrc

open()别用了,改用io.open()

其它的细微差别,多读一下py3k的"what's new"基本上搞定

类型:Python,创建时间:一月 1, 2012, 5:32 p.m. 点击查看完整内容。。。
编译Python源代码

在日常生活中,Python代码一般是不编译的,几个py文件复制来就能用。再加上脚本语言的名头,有些不太了解Python的朋友就以为Python没有编译这个过程。其实,虽然Python是脚本语言,但它与Java和C#一样,只能执行字节码。只是Python将编译过程隐藏起来,不大明显而已。今天这篇笔记详细记述一下Python的编译过程以及一些技巧:

  1. "优化"编译后的字节码。
  2. 禁止生成".pyc"文件。
  3. "反编译"Python字节码。
类型:Python,创建时间:一月 1, 2012, 5:05 p.m. 点击查看完整内容。。。
一个判断密码强度的函数
def judgePasswordStrength(password):
    strengthLength = max(0, len(password) - 5)
    from string import ascii_lowercase, ascii_uppercase, digits, punctuation
    flags = [bool(set(password) & set(s)) \
            for s in [ascii_lowercase, ascii_uppercase, digits, punctuation]]
    return min(flags.count(True), strengthLength)
类型:Python,创建时间:一月 1, 2012, 4:55 p.m. 点击查看完整内容。。。
(翻译)为什么Python的字符串是不可变对象

翻译自http://effbot.org/pyfaq/why-are-python-strings-immutable.htm

不可变对象是指一旦生成后不能被改变的对象。他经常与可变对象相提并论。比如Python的tuplelist,它们的行为有点类似。但是可以list对象内添加新的元素。而tuple则不可以。Python的字符串被设计成不可变对象有几个优点。

首先,可以提高性能。假定字符串是不可变对象,意味着字符串具有确定而不可变的存储需求,解释器可以为它分配一段固定的内存。这也是为什么要分为tuplelist两种类型的原因之一。让字符串成为不可变对象还可以让解释器重用该对象。比如,CPython在实现中预先申请了所有的单字节节符,并且,如果字符串运算后的结果与运算前相同,就会返回运算前的字符串(*)。

另外,在Python里,字符串就像数字一样,被认为是表示思想的最基本的材料。在Python里,没有任何方法可以把数字8变成其它东西,同样,也没有办法把"eight"这个字符串变成其它东西。

另外,使用不可变数据结构(immutable data structures),比如字符串,元组,强调了一种无副作用的编程方式。采用这种编程方式所编写的函数接收输入的参数,进行运算,然后返回一个容纳结果的新对象。而不是修改输入的参数,使它变成运算结果。当然了,有时候必须做一些有副作用的操作,比如修改对象的状态。这种事最好仔细考虑一番,因为无副作用的编程哲学能够让你的代码更加模块化,使其独立于其它代码。

类型:Python,创建时间:一月 1, 2012, 4:50 p.m. 点击查看完整内容。。。
Qt窗口的删除、析构

Qt内关于窗口的删除是一个复杂的事情。接下来详细地讲一讲。

当我们创建一个窗口时,如果这个窗口是一个顶级窗口,准确地说是w.windowFlags().testFlag(Qt.Window) is True的窗口,Qt会自动附加一个Qt.WA_QuitOnClose属性。它的意思是,窗口被关闭了,qApp.lastWindowClose信号会被触发。

默认情况下,qApp接收到此信号后会退出程序,这个行为相当于在初始化程序时:

qApp.lastWindowClosed.connect(qApp.quit)

要修改这个默认行为,可以设置QApplicationquitOnLastWindowClosed属性,比如:

qApp.setQuitOnLastWindowClosed(False)

通常,用户可以点击窗口的关闭按钮关闭窗口,或者当系统关闭的时候,窗口也会被关闭。我们可以通过重载窗口的closeEvent()函数控制关闭动作,比如询问用户要不要保存文档,或者只是最小化窗口。下面是一个例子:

def closeEvent(self, event):
    if self.maybeSave():
        self.saveSettings():
        event.accept()
    else:
        event.ignore()

我们也可以在菜单里设置一个退出命令,点击它的时候调用窗口的close()函数即是关闭窗口。

关闭窗口之后,通过我们还要手动销毁这个窗口,释放它所占用的内存。对此Qt提供了一个简便的办法,只要将窗口的Qt.WA_DeleteOnClose属性设置为true,Qt会自动帮我们销毁这个窗口。

类型:Python,C++ & Qt4,创建时间:一月 1, 2012, 4:42 p.m. 点击查看完整内容。。。
猜猜这人是谁(转载)

有一个男人,他19岁娶了18岁的女友、

24岁時和只有18岁的秘书交往并結婚

28岁见到1岁的女嬰,开始光源氏计划、

在31岁到日本旅行认识一名15岁的女仆,

隔年认识10岁的萝莉,

在日本旅行期间就周旋于女仆和萝莉之间,

38岁和萝莉結婚、39岁回到中國,

49岁光源氏计划成功,把22岁的小妹妹带回家,

后來活到59岁死亡。

请问这人生的贏家是哪个历史人物?

类型:随感,创建时间:一月 1, 2012, 4:37 p.m. 点击查看完整内容。。。
异端,去死吧(转载)

一个人走过海旁,看见另一个人想跳海自杀。

他走上前去劝说「先生,不要跳下去!」

那人问道:「为甚么?」

他说:「生命是美好的嘛!你是无神论者还是有宗教信仰?」

那人答:「我有宗教信仰。」

「佛教、道教、回教还是基督教?」

「基督教」

「罗马天主教还是新教?」

「新教」

「我也是新教呢!圣公会还是浸信会?」

「浸信会」

「太好啦!我也是浸信会,你是Baptist Church of God还是Baptist Church of the

Lord? 」

「Baptist Church of God. 」

「真是太奇妙啦!我也是,那你是原教旨的Baptist Church of God还是改革派的?」

「改革派的」

「1879年的改革派还是1915年的?」

「1915年的改革派。」

那人朝他屁股一脚把他踢进海里:「异端!去死吧!」

类型:LinuxApp,随感,创建时间:一月 1, 2012, 4:36 p.m. 点击查看完整内容。。。
使用M2Crypto加密数据

本文是一个M2Crypto的基础教程。介绍了如何使用M2Crypto完成以下任务:

  1. 如何使用MD5、SHA1等消息散列算法。
  2. 使用对称加密算法加密数据。
  3. 生成RSA密钥
  4. 生成DSA密钥
  5. 载入DSA密钥与RSA密钥
  6. RSA类型的操作——使用RSA加密、解密、签名、认证;保存RSA密钥
  7. 一个小型的CA,电子证书。

研究M2Crypto时参考了OpenSSL的源代码,因此本文对学习OpenSSL的同学或许也有些参考意义。

类型:Python,创建时间:一月 1, 2012, 4:35 p.m. 点击查看完整内容。。。
聊聊Pyhon的encodings

本文讨论python各种奇形怪状的编码:

  • base64
  • bz2
  • hex
  • idna
  • punycode
  • quopri
  • raw_unicode_escape
  • rot_13
  • string_escape
  • undefined
  • unicode_internal
  • utf_8_sig
  • uu
  • zlib
类型:Python,创建时间:一月 1, 2012, 9:15 p.m. 点击查看完整内容。。。
使用QToolBox时,pyuic4的一个编译错误

有时候QtDesigner生成的窗口如果包含QToolBox,使用pyuic4编译的时候会出错。经过调查,我发现主要是因为QtDesigner在创建QToolBox的页时会自动生成页面的名字。可能是因为翻译的问题,页面的名字是中文的(page变成)。页面的名字会编译成python的变量名。在python3k之前,使用中文作为python的变量名显然是不合适的。所以会提示错误。

如果发现pyuic4发生错误,可以试着加入调试选项:pyuic4 -d main.ui。 可以解决很多像QToolBox那样的错误。

类型:Python,C++ & Qt4,创建时间:一月 1, 2012, 2:54 p.m. 点击查看完整内容。。。
使用Qt实现从资源管理器中拖动文件到应用程序的功能

我是EditPlus和FileZilla的用户。这两个软件都支持文件拖拽。我们可以从资源管理器中拖动一个文件到EditPlus的窗口,EditPlus就会自动打开这个文件。或者拖到FileZilla的远程窗口内,FileZilla就会自动将文件上传到服务器。我经常希望自己的软件也支持拖动的操作。

作为基本功能,大多数操作系统都各自定义了拖放所需的通信协议。Qt对此做了一个很好的封装。基本的流程是:当用户从其它应用程序拖动文件、文本、图像等到Qt程序时,Qt会自动产生一个DrapEnterEvent,应用程序可以判断数据是不是可以处理的。如果能处理,就反馈给Qt,这样的话,用户就会看到一个接受拖放的标识。待用户放开鼠标时,Qt再产生一个DropEvent。最后应用程序从事件中取出数据进行处理。

那么应用程序如何判断程序是否可以处理拖放的数据呢?很简单,数据中包含了MIME类型。MIME类型是一个用于标识二进制数据类型的Internet标准。很多朋友可能习惯通过文件的扩展名来判断数据类型,但是扩展名只有短短的几个字符,常常有歧义。通常,如果应用程序要处理文本,就判断MIME类型是不是"text/palin",如果要处理JPEG图像,就判断MIME类型是不是"image/jpeg",等等。同一段数据通常包含多种MIME类型,比如拖动富文本时,数据中可能包含纯文本、HTML文本、图像。应用程序可以选择处理所支持的数据格式。

具体如何处理从资源管理器拖动的文件呢 ?请点击查看正文。

类型:Python,C++ & Qt4,创建时间:一月 1, 2012, 8:52 p.m. 点击查看完整内容。。。
小技巧:让Win键在KDE中更有用(转载)

http://blog.gmsh.pp.ru/2009/08/tips-make-win-key-useful-in-kde/

从 Windows迁移到 Linux 上的用户,可能保持着按 WindowsKey(Windows键,标准键盘最下一行的那个视窗键)打开Windows开始菜单的习惯。但是在 某些 Linux 发行版上(比如笔者的openSUSE 11.1,KDE 4.3环境)上 WindowsKey 并没有绑定到 KickOff 菜单上。可以尝试在 KDE 控制中心 (KDE control panel)里面修改,而 KDE 的快捷键只允许非修饰键(Modifier Key)和 组合键,WindowsKey 恰恰是修饰键,直接绑定 WindowsKey 是不可行的。下面,笔者介绍一个技巧,使 WindowsKey 绑定到 KDE 4.3 的 KickOff 菜单上。这里用了更改键盘映射的方法。

详细过程请点击查看正文。

类型:LinuxApp,创建时间:一月 1, 2012, 8:45 p.m. 点击查看完整内容。。。
禁止python在运行的时候自动生成.pyc文件

有没有觉得,有时候python的.pyc文件很讨厌呢?虽然它们能加快加载速度,但是看见那一堆堆的文件,又不能放到SVN里,实在是很烦。

现在python2.6新增了一个特性,只要把环境变量PYTHONDONTWRITEBYTECODE设置为x,就不再会生成.pyc文件了。在windows下修改环境变量的方法是:右键点击“我的电脑” ->属性->高级->环境变量。在Linux下可以修改~/.profile

export PYTHONDONTWRITEBYTECODE=x
类型:Python,创建时间:一月 1, 2012, 2:40 p.m. 点击查看完整内容。。。
datetime和date类型与字符串之间的互转

不说什么,看代码:

#从sqlite3模块抄过来的东西,用于datetime,date到字符串之间的相互转换
def adapt_date(val):
    return val.isoformat()

def adapt_datetime(val):
    return val.isoformat(" ")

def convert_date(val):
    return datetime.date(*map(int, val.split("-")))

def convert_timestamp(val):
    datepart, timepart = val.split(" ")
    year, month, day = map(int, datepart.split("-"))
    timepart_full = timepart.split(".")
    hours, minutes, seconds = map(int, timepart_full[0].split(":"))
    if len(timepart_full) == 2:
        microseconds = int(timepart_full[1])
    else:
        microseconds = 0

    val = datetime.datetime(year, month, day, hours, \
            minutes, seconds, microseconds)
    return val
类型:Python,创建时间:一月 1, 2012, 2:33 p.m. 点击查看完整内容。。。
Python的XMLRPC简介及小技巧

我觉得,SimpleXMLRPCServer模块可以说是Python的招牌菜。

编写客户端提交数据到服务器处理是程序员最常碰到的几个问题之一。各种不同的语言对此都有相应的解决方案。比如Unix下,C程序员们可以用SUNRPC,Java程序员则使用RMI来处理。大多数语言还都可以使用Web Service或者ICE。它们的使用方法类似,编写一个接口定义文件,用一个工具处理并生成代码,加入到工程中,最后编译生成目标文件运行。有用过这类工具的朋友们,脑子里应该都会闪出一个字——烦!真的是谁用谁知道。

Python同样也提供了一个基于XMLRPC的解决方案,不过用法很简单:

  1. 首先,就像在编写普通的程序那样子编写服务器。
  2. 接着使用SimpleXMLRPCServer模块运行XMLRPC服务器,在其中注册服务器提供的函数或者对象。
  3. 最后,在客户端内使用xmlrpclib.ServerProxy连接到服务器,想要调用服务器的函数,直接调用ServerProxy即可。

本文介绍xmlrpc的基本用法以及几个注意事项。

类型:Python,创建时间:一月 1, 2012, 2:30 p.m. 点击查看完整内容。。。
Qt程序如何用PostMessage向一个窗口输入文字

写一些监控类程序的时候,有时候会要求某个条件满足的时候就向某个窗口 写入一堆文字。我首先想到的是PostMessage。对于文本框之类的控件,可以使用WM_SETTEXT这个消息。如果不是文本控件,只好使用WM_CHAR写入一个个的文字。 基本的用法是这样子的:

PostMessage(hwnd, WM_CHAR, c, 0);

如果编译的时候定义了UNICODE。那其中的c是文字的utf-16码(TCHAR)。Qt的QChar有个unicode()方法,可以取得utf-16内码。

QString s=tr("一段中文和Enlish Text");
foreach(QChar c, s)
    PostMessage(hwnd, WM_CHAR, c.unicode(), 0);
类型:C++ & Qt4,创建时间:一月 1, 2012, 2:12 p.m. 点击查看完整内容。。。
Python的__del__()方法

简而言之,__del__方法相当于其它语言里的析构函数。不过,由于Python的一些特性,在使用__del__需要注意一些问题:

  1. 因为垃圾收集机制处理循环引用(A使用B,B又使用了A)的时候总不尽如人意。 所以__del__并不总是会被调用。

  2. __del__可能在Python退出的时候被调用。此时很多变量都已经被释放, 所以__del__对外部的依赖要尽可能的小。

  3. __del__函数内不能引入新的模块。

  4. Python提供了try/finally这样的语法,一些资源释放的东西,最好还是放在finally块内解决,而不是放到__del__方法内。

类型:Python,创建时间:一月 1, 2012, 12:31 p.m. 点击查看完整内容。。。
最讨厌Python 2.x的编码问题了

本粗人在写程序的时候习惯这样子:

print "中文"

显然,这个写法是不具可移植性的。因为,在windows下默认编码是gbk,在很多linux下面默认编码是utf-8。如果源代码的编码是gbk,在windows下可以工作得很好,如果源代码是utf-8,在windows下会打印出一堆乱码。好一点的作法是

print u"中文"

这样的话,在不论源代码的编码是什么,也不论操作系统是什么,都可以打印出正确的字符。可是如果这样子就麻烦了:

name=third_party_module.get_system_username()
print u"你好,%s"%name

third_party_module.get_system_username()返回一个当前登录的用户真实名字。但是他返回的到底是什么编码的我们不知道。因为unicode()函数默认使用当前系统的默认编码。倘若name的编码与当前系统默认的一样,一切OK。如果不一样,问题就麻烦了。幸好返回时使用的一般是当前系统默认编码。

最麻烦的:

name=third_party_module.get_system_username()
client_socket.send(name)

字符串被发送到网络上,到达运行着不同操作系统的远程主机上。远程的主机怎么知道这是什么编码呢?最近经常遇到这样的问题,实在很郁闷。

类型:Python,创建时间:一月 1, 2012, 12:29 p.m. 点击查看完整内容。。。
八十后的我们为何不结婚(转载)

一挚友发现,致所有徘徊在围城门口的朋友 80后早期的我们,按理说现在也老大不小了,搁在解放前这个年纪孩子都满地跑了。看着身边也有不少同龄人结婚生子了,可大部分还都踌躇着,恩,一提结婚 就抽搐!为什么我们还死皮赖脸的拽着青春的尾巴不结婚呢?让我好好想想。

我想,首先,心态问题。在以前,结婚根本就不是个事儿,一到岁数找个差不多的就办了,那时候大家都一穷二白,干脆利索,也没人在乎爱多爱少的。可现在这人 类进化得越来越把自己当回事儿了,什么人品、家世、长相、工作、学历、前途、甚至业余爱好没有一样不琢磨的,反复研究,深入探讨,仔细对比,辗转反侧…… 眼看着就把简单问题复杂化,两人问题扩大化!结果越琢磨越糊涂,这婚就结不了了!结婚嘛,俩人搭伙过日子,本来多简单一事,硬让我们弄得比制造航天飞机还 罗嗦。追其原因,我觉得是我们对结婚的目的不纯粹了,总想通过婚姻得到一些其他的附加价值。例如房子、车子、还有未来的好日子。当你想通过一张纸来得到一 辈子的东西,是有点难。

类型:随感,创建时间:一月 1, 2012, 12:24 p.m. 点击查看完整内容。。。
Linux下如何挂载一个ISO文件

挂载一个iso文件的方法:

mount /root/CentOS.iso /mnt/centos -t iso9660 -o loop=/dev/loop1

其中/root/CentOS.iso是iso文件的路径。/mnt/centos是挂载到的目录。-t iso9660指明了ISO文件的文件系统格式。-o loop=/dev/loop1指明了使用哪个loopback文件。如果/dev/loop1已经被使用了,可以使用其它的loopback文件,/dev/loop2这样子。

类型:LinuxApp,创建时间:一月 1, 2012, 12:22 p.m. 点击查看完整内容。。。