如何设计插件式结构的程序,兼谈Python语言的动态性

为了扩充软件的功能,通常我们会把软件设计成插件式结构。Python这样的动态语言天生就支持插件式编程。与C++相比,Python已经定义好模块的接口,想要载入一个插件,一个__import__()就能很轻松地搞定。不需要特定的底层知识。而且与C++等静态语言相比,Python的插件式结构更显灵活。因为插件载入后,可以利用Python语言的动态性,充分地修改核心的逻辑。

本文不止用几个最简单的程序示范了如何设计插件式结构。还演示了插件的两种布署方法以及一些小技巧。详细内容请点击查看全文。

类型:Python,创建时间:三月 23, 2012, 5:46 p.m. 点击查看完整内容。。。
Python中使用线程的技巧

这篇长文介绍了Python如何创建一个新线程,以及几个注意事项:

  1. 创建线程的两种方法,以及它们的正确写法。
  2. 创建线程的第三种写法。
  3. 如何“强制地”结束一个线程。
  4. 不要在线程里面import新模块
  5. 不要使用PyQt的QThread类。
  6. 不要在非主线程里面使用QObject的对象。
类型:Python,C++ & Qt4,创建时间:三月 14, 2012, 8:59 p.m. 点击查看完整内容。。。
最全的Tkinter教程与参考手册

这本是我见过的最全的Tkinter教程与参考手册。主要介绍了Tkinter的Layout模型、控件的标准属性、事件。详细列出了每一种控件的属性的意义。里面还有很多的代码例子,实在是一本不可多得的好书。

点击下载

类型:Python,创建时间:三月 14, 2012, 11:16 a.m. 点击查看完整内容。。。
在PyQt里面如何做长操作时同时更新GUI

经常看到有人问在PyQt里面如何做长操作的时候更新GUI。我自己总结了几种方案,以及他们的适用场合:

  1. 使用processEvents(),适合每次处理时间短的情况,缺点是CPU占用可能很大。
  2. 用threading启动工作线程,再用QMetaObject.invokeMethod()向主线程传递跨线程的信息。
  3. QProgressDialog。有同步与异步两种方法。
  4. 把长的操作分为小的操作,适合每次处理都是异步的或者很复杂的情况。

第四种方案不常用,但是当你的处理过程本身是异步的时候就会用到。第一、第二方案都不错,优点是灵活。第三种方案也常见,优点是模态对话框阻止用户的其它操作,可以随时取消。缺点是一个对话框挡在那里,相当地影响用户体验。

类型:Python,C++ & Qt4,创建时间:一月 17, 2012, 3:53 p.m. 点击查看完整内容。。。
Django的MEDIA_ROOT和STATIC_ROOT

在水木的Python版问了一下,MEDIA_ROOT主要是用来放置上传的文件。Django的ORM有个特殊的字段叫做FileField是用来存储文件的。不过实际上并不会把文件内容存到数据库里面——因为大多数数据库保存文件时效率低,而是保存在文件系统里面。FileField只记录一个路径。FileField可以像个Python的file类型那样读写。

在开发的时候MEDIA_ROOT不应该存放任何文件。它应该指向一个空的目录。运行Django的开发服务器时,需要在urls.py里面加入一个MEDIA_URL的映射,才能正常显示上传的内容:

from django.conf import settings

if settings.DEBUG:
    urlpatterns += patterns(",
            url(r"^media/(?P<path>.*)$", \
                "django.views.static.serve", \
                {"document_root": settings.MEDIA_ROOT,}),
)

当工程被布署到Apache时也要记得给MEDIA_URL做个映射。

STATIC_ROOT是Django 1.3新增的特性。如同字面上的意思。保存在这个目录里面文件被当成静态文件处理。不过,千万不要把自己辛苦写的JavaScript、图片等静态文件放到里面去,接着看下去就知道了。与STATIC_ROOT搭配使用的还有STATIC_URLSTATICFILES_DIRS两个变量。STATIC_URL一般用默认的/static/,用于指定的静态目录的URL。STATICFILES_DIRS则指定一个工程里面哪个目录存放了与这个工程相关的静态文件,它是一个列表。假定在STATICFILES_DIRS有一个目录是"/dolphin/besteam/pages/static",其中有一个文件是common.js。那么,在浏览器里面输入http://localhost:8000/static/common.js就可以访问这个JavaScript文件了。

类型:Python,创建时间:一月 1, 2012, 7:14 p.m. 点击查看完整内容。。。
将Python程序打包成.zip文件并发布

在部署Python程序的时候。一般是把所有的源代码复制到目标机器上。我发现一个更好的办法是把源代码打包成.zip文件,然后直接运行这个.zip文件。比如:

python besteam.zip

它的秘密是在.zip文件中包含一个__main__.py,当python运行这个zip时,会自动找到它并运行。__main__.py的内容一般是调用主脚本。一行即可,比如:

import besteam
类型:Python,创建时间:一月 1, 2012, 7:02 p.m. 点击查看完整内容。。。
使用非对称密钥登录SSH服务器

通常登录SSH服务器都使用用户名与密码。每次都输入用户名和密码比较麻烦,特别是有很多台机器的时候。Windows下的putty支持大多数的SSH认证方式,其中就包含了非对称密钥登录。步骤其实很简单,

  1. 使用puttygen.exe生成非对称密钥,将私钥保存起来,将公钥传输到远程主机上,假定保存到~/id_rsa.pub。然后用下面这台命令放到认证文件里:

    cat ~/id_rsa.pub >> ~/ssh/authorized_keys
    
  2. 运行putty.exe,首先载入Session

  3. 在putty配置对话框的Connection->Data页的Auto-login username里填上登录所使用用户名,比如root

  4. 在配置对话框的Connection->SSH->Atuh页的Private key file for authentication内添入私钥所在的路径。

  5. 保存Session。下次登录的时候就不需要输入用户名和密码了

类型:LinuxApp,创建时间:一月 1, 2012, 6:59 p.m. 点击查看完整内容。。。
让VMWare进入全屏模式的时候不显示最顶上的工具栏

相当于进入Exclusive Mode

方法是编辑C:\Document and Settings\username\Application Data\VMWare\preferences.ini,其中的username请替换成自己的用户名。在其中加入

pref.fullscreen.v5 = "true"
类型:随感,创建时间:一月 1, 2012, 6:57 p.m. 点击查看完整内容。。。
将winodws server 2008 r2配置成桌面环境

安装完Windows Server 2008 r2后第一件事是安装驱动、更新系统以及注册。注册的方法用微软给学生发的免费授权。貌似国内很多学校的学生都可以得到这个免费的授权,微软为了垄断市场,真是舍得啊。

更新后依http://www.win2008workstation.com/的提示配置好桌面环境。有几个内容:

1、创建新的非特权用户。平时尽量使用非特权用户,避免感染木马时整个系统都受到影响。安装软件的时候一定要仔细看一看,不然有些软件会安装IE插件什么的,清理起来很麻烦。

2、关闭"关闭事件跟踪器"。禁用登录时按"Ctrl+Alt+Del"的功能。这两个设置可以在gpedit.msc里面找到。

3、启用声音。在系统右下角的通知栏里面点几下就可以启用了。不过启用了声音服务之后,播放音乐还是会卡。可以在注册表里面找到HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Multimedia\SystemProfile\SystemResponsiveness,将它的值修改为0x14。喜欢的话,可以在管理面板的属性里面选择一个声音主题。

更多内容请点击查看正文。

类型:随感,创建时间:一月 1, 2012, 6:56 p.m. 点击查看完整内容。。。
debian6.0修改Grub2支持高分辨率console

以前配置grub1的方法是修改/etc/grub.conf,而grub2则是修改/etc/grub.d/里面的脚本。里面的脚本过于深奥,我稍微查看了一下,改分辨率的方法是修改/etc/default/grub的内容:

在GRUB_CMDLINE_LINUX里面增加内核参数:

GRUB_CMDLINE_LINUX="vga=792"

注意要注释掉:

# GRUB_TERMINAL=console

默认这一行是注释掉的,不然vga就没用了。

做完调用grub-mkconfig -o /boot/grub/grub.cfg刷新一下配置。

类型:LinuxApp,创建时间:一月 1, 2012, 6:53 p.m. 点击查看完整内容。。。
Python的类、对象,以及classmethod的意义

先看一下这两行代码:

>>> class Fish:pass
>>> f=Fish()

f就是Fish类的实例,它是一个对象(object),很明显吧。 Fish是类,它也是一个对象(object),如果你以前学的是C++或者Java,可能会难以理解。 不管怎么样,在Python内部,它们都用一个PyObject结构体表示,你可以修改对象的属性, 调用它们的方法。

类与实例两种对象有什么区别呢,下面的代码运行于python 3.1版本:

>>> Fish.isAnimal=True
>>> print(f.isAnimal)
True

我们定义Fish是一种动物,显然f更是一种动物了。

>>> f.name="老鱼"
>>> print(Fish.name)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: type object 'Fish' has no attribute 'name'

我们定义f这条鱼的名字是"老鱼"。这时候,Fish并不会自动拥有名字这个属性,总不能说 鱼都是叫“老鱼”吧。

类的实例可能比较好理解,但是类居然可以有属性,可能有些C++/Java程序员难以理解。

使用classmethod修饰的函数第一个参数是类对象。平时它没什么用,只有继承关系比较复 杂的时候才能派上用场。我以前学classmethod的时候写过一段代码:详情请点击查看正文。

类型:Python,创建时间:一月 1, 2012, 6:46 p.m. 点击查看完整内容。。。
打造自己习惯的Python命令行环境

使用过一段时间的Python之后,大多数朋友可能已经发现自己经常使用的是Python某一部分的功能。比如习惯拿Python来当计算器的朋友,最喜欢的是运行Python的命令行之后就打一个:

from __future__ import division
from math import *

每次运行之后都要输入这些命令不免麻烦,幸好Python开发者早就替我们考虑好这个问题了。可以通过设置"PYTHONSTARTUP"这个环境变量让Python命令行每次运行后都自动做这些事。

比如,我们可以编写一个名为startup.py的文件,它的内容是:

from __future__ import division
from math import *

假设将它保存到H:\Documents\myconfig\startup.py。然后设置环境变量PYTHONSTARTUP=H:\Documents\myconfig\startup.py。下次运行Python命令行之后,输入sqrt(2)试试。

类型:Python,创建时间:一月 1, 2012, 6:33 p.m. 点击查看完整内容。。。
怎么样将VMWare默认的Ctrl+Alt快捷键改为右Alt键

习惯使用Virtual Box然后改用VMWare的朋友可能会对它默认的右Alt快捷键印象深刻,特别是对安装Linux虚拟机的朋友来说更是如此。比如,在Linux下,经常要按Ctrl+Alt+Fn来切换控制台,Virtual Box直接按下此组合键即可,而VMWare则需按Ctrl+Alt+Space,然后放开Space按Fn才有效。如果直接设定为不区分左右的Alt键也不行,菜单命令和Emacs快捷键都会失效。

那,能不能让VMWare跟Virtual Box一样呢?直接使用VMWare的首选项对话框目前是不行的,只能配置使用Alt键或者Ctrl键,不能配置左右。后来通过Google,我发现了一种修改VMWare配置文件的方法。原来,VMWare并非不支持此功能,而是隐藏起来了。

首先要找到VMWare的配置文件。它位于C:\Document and Settings\username\Application Data\VMWare\preferences.ini

类型:随感,创建时间:一月 1, 2012, 6:28 p.m. 点击查看完整内容。。。
在Windows下使用KDE的Phase样式

KDE的Phase样式是我最喜欢的样式之一。我觉得它看起来非常稳重、简洁,很适合作为日常工作的默认样式。原来以为它只能工作在KDE环境,直到半年前看KDE代码的时候才发现它原来是一个Qt样式,因此,开发Windows软件的时候完全也可以使用它。

在Windows下编译Phase样式很简单,只要把Phase的三个文件复制过来,假定放在D:\phase下。然后编写这么一个工程文件:

#phase.pro
TEMPLATE = lib
CONFIG += plugin
HEADERS += bitmaps.h phasestyle.h
SOURCES += phasestyle.cpp

接下来Qt程序编译标准步骤:

h:\phase> qmake
h:\phase> mingw32-make release

编译成功后,可以在h:\phase\release下找到phase.dll文件,复制到Qt的$QTDIR\plugins\styles目录后就可以使用Phase样式了。

类型:C++ & Qt4,创建时间:一月 1, 2012, 6:01 p.m. 点击查看完整内容。。。
PyQt里让文本编辑器自动滚动

前两天看txt小说的时候,手头找不到小说阅读器,就顺手写了一个。主要功能是让文字自动滚动。原理超简单,让QTextBrowser的滚动条每隔一段时间往下拉一点就可以了。好了,上代码:

vb=self.textBrowser.verticalScrollBar()
if vb.value()>=vb.maximum():
    return
vb.setValue(vb.value() + 2)

据我试验,QPlainTextEdit滚动条拉动时以行为单位,每次滚动只能下拉一行。用QTextEditQTextBrowser不会有这个问题。

类型:Python,C++ & Qt4,创建时间:一月 1, 2012, 5:54 p.m. 点击查看完整内容。。。
中国式女权是伪女权,本质是要求不劳而获–非诚勿扰(转载)

现在的女人有个特点就是人生观的取舍带有非常浓重的功利色彩,既封建又现代,既大男人主义又女权主义。

1,结婚之前,她们要这要那,要房子要车子要票子,还要求男人得能干会赚钱,而自己能力如何无所谓(结婚以后也要求男人挣钱养家,而自己的收入自己留下来 做零花)。这实际上是继承了封建社会男尊女卑的传统,想把自己像一个富家大小姐那样风风光光的嫁出去,然后对方像养阔太太一样把自己养起来,而且对方既然 要求自己“做对方家“的人,是把自己“拿“走了,那么对方当然还得付给自己家一大笔彩礼。就好像买卖东西一样,这本质上是延续封建社会的传统。

2,结婚以后,又反过来了,放下了封建主义的幌子,开始挥动女权主义的大棒。她们嫁到了男家,却三天两头往娘家跑,往外跑忙自己赚钱,赚了钱也不供给家 用,而是留着自己零花;也不肯干家务,在家务上开始要求男女平等,甚至干脆把家里的家务都推给男方,声称自己是女性应该多受照顾,那些要求女性包办家务的 行为是老封建。离婚的时候,继续所谓女权思想,要求男方把房子车子孩子票子都给自己,声称这是现代社会出于所谓的“两性公平“地考虑。

这可真是怪了!她们到底奉行封建男权思想,还是奉行女权主义?

类型:随感,创建时间:一月 1, 2012, 5:50 p.m. 点击查看完整内容。。。
窗口最小化后隐藏

通常最小化的窗口会在任务栏上显示一个按钮。当用户按一下这个按钮,窗口就还原了。这是一个被大多数桌面环境,比如Windows,KDE,GNOME所采用的普遍设计。不过,因为任务栏通常只是桌面边上一小行,容纳不了很多按钮,用户通常希望把那些不常用的程序隐藏起来,只在通知栏显示一个小图标,要使用的时候再点击那个小图标恢复窗口。这种作法最典型的例子是QQ和Winamp。

最基本的思路是拦截窗口的最小化事件:

void MyWindow::changeEvent(QEvent* event)
{
    if(event->type()==QEvent::WindowStateChange)
    {
        if(windowState() & Qt::WindowMinimized)
        {
            QTimer::singleShot(0, this, SLOT(hide())); //修改这一行
            mSystemTrayIcon->show();
        }
    QMainWindow::changeEvent(event);
}
类型:C++ & Qt4,创建时间:一月 1, 2012, 5:49 p.m. 点击查看完整内容。。。
编写兼容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. 点击查看完整内容。。。