posts - 20,  comments - 21,  trackbacks - 0

py2exe是实用的python脚本工具,可以将python脚本程序转换为exe执行文件。这样你的python程序就可以没有安装python运行时环境的电脑里运行了。py2exe方便地提取出python运行时所需要的文件档案,你需要做的就是写一个两三行的安装脚本文件。

py2exe可以从http://sourceforge.net/projects/py2exe/下载,唯一需要注意的是下载与你python版本号对应的版本,简单的英文教程http://www.py2exe.org/index.cgi/Tutorial非常容易入门。

对早先写的一个代理验证脚本进行exe文件封装作为示例,这测试脚本名为HttpProxyTester.py。

首先,最好测试运行一下待封装的脚本以确定没有问题,然后在HttpProxyTester.py脚本的同级目录新建一setup.py文件。

# setup.py

from distutils.core import setup
import py2exe

setup(console=['HttpProxyTester.py'])

上面的文件首先引入了distutils模块,这模块随python安装分发的,也就是说内置的。接着导入py3exe模块,它其实对distutils做了一些功能扩展。接下来的语句说明是控制台运行。对于windows的GUI模式运行,而不出控制台窗口,则需要setup(windows=['xxx'])之类指令,这对于pyWidget程序将很有用。

在完成安装脚本后,接下来就是在控制台下运行这脚本。

>python setup.py py2exe

这时会打印出许多log信息,并在同级目录下出现两个新的文件夹:build和dist。build文件夹下是py2exe生成的一些临时文件,dist就是需要分发的文件内容,可以这文件夹打包,然后在别的机子上运行了。

总之,py2exe非常简单实用,三分钟就可以搞定。

posted @ 2008-08-11 19:19 len 阅读(46) | 评论 (0)编辑 收藏

Python在处理功能复用和功能颗粒度划分时采用了类、模块、包的结构。这种处理跟C++中的类和名字空间类似,但更接近于Java所采用的概念。

类的概念在许多语言中出现,很容易理解。它将数据和操作进行封装,以便将来的复用。

模块

模块,在Python可理解为对应于一个文件。在创建了一个脚本文件后,定义了某些函数和变量。你在其他需要这些功能的文件中,导入这模块,就可重用这些函数和变量。一般用module_name.fun_name,和module_name.var_name进行使用。这样的语义用法使模块看起来很像类或者名字空间,可将module_name 理解为名字限定符。模块名就是文件名去掉.py后缀。下面演示了一个简单的例子:

#moduel1.py
def say(word):
    print word

#caller.py
import module1

print __name__
print module1.__name__
module1.say('hello')
$ python caller.py
__main__
module1
hello

例子中演示了从文件中调用模块的方法。这里还展示了一个有趣的模块属性__name__,它的值由Python解释器设定。如果脚本文件是作为主程序调用,其值就设为__main__,如果是作为模块被其他文件导入,它的值就是其文件名。这个属性非常有用,常可用来进行模块内置测试使用,你会经常在一些地方看到类似于下面的写法,这些语句只在作为主程序调用时才被执行。

if __name__ == '__main__':
    app = wxapp(0)
    app.MainLoop()

模块搜索路径

上面的例子中,当module1被导入后,python解释器就在当前目录下寻找module1.py的文件,然后再从环境变量PYTHONPATH寻找,如果这环境变量没有设定,也不要紧,解释器还会在安装预先设定的的一些目录寻找。这就是在导入下面这些标准模块,一切美好事情能发生的原因。

import os
import sys
import threading
...

这些搜索目录可在运行时动态改变,比如将module1.py不放在当前目录,而放在一个冷僻的角落里。这里你就需要通过某种途径,如sys.path,来告知Python了。sys.path返回的是模块搜索列表,通过前后的输出对比和代码,应能理悟到如何增加新路径的方法了吧。非常简单,就是使用list的append()或insert()增加新的目录。

#module2.py
import sys
import os

print sys.path
workpath = os.path.dirname(os.path.abspath(sys.argv[0]))
sys.path.insert(0, os.path.join(workpath, 'modules'))
print sys.path
$ python module2.py
['e:\\Project\\Python', 'C:\\WINDOWS\\system32\\python25.zip', ...]
['e:\\Project\\Python\\modules', 'e:\\Project\\Python', 'C:\\WINDOWS\\system32\\python25.zip', ...]

其他的要点

模块能像包含函数定义一样,可包含一些可执行语句。这些可执行语句通常用来进行模块的初始化工作。这些语句只在模块第一次被导入时被执行。这非常重要,有些人以为这些语句会多次导入多次执行,其实不然。

模块在被导入执行时,python解释器为加快程序的启动速度,会在与模块文件同一目录下生成.pyc文件。我们知道python是解释性的脚本语言,而.pyc是经过编译后的字节码,这一工作会自动完成,而无需程序员手动执行。

在创建许许多多模块后,我们可能希望将某些功能相近的文件组织在同一文件夹下,这里就需要运用包的概念了。包对应于文件夹,使用包的方式跟模块也类似,唯一需要注意的是,当文件夹当作包使用时,文件夹需要包含__init__.py文件,主要是为了避免将文件夹名当作普通的字符串。__init__.py的内容可以为空,一般用来进行包的某些初始化工作或者设置__all__值,__all__是在from package-name import *这语句使用的,全部导出定义过的模块。

posted @ 2008-07-24 19:42 len 阅读(62) | 评论 (0)编辑 收藏

应用程序国际化,在开源世界里常以i18n被提及,i18n是Internationalization的简写,正好18个字母。在wxPython程序进行i18n,如果字符串是编码在源文件中时,完全可按照python程序的i18n的方法,即使用gexttext和locale模块。而wxPython程序在使用XRC文件做为界面资源时,则应使用wx.Locale模块,它封装了区域化相关的操作。i18n,或者国际化实际上涉及到语言习惯,数字格式等等类别的内容。这里只介绍语言多国化,将一个简单的英文程序转换为中文,涉及到源文件,可从这里下载。

创建PO文件

PO文件是Portable Object文件的简称,它包含需要翻译的字符串。我们需要从源文件进行提取。首先,对源文件test.py编辑,标识代码里需要翻译的字符串内容。我们使用_("xx")的方法,这种形式可能在许多开源源代码中见识过。

#加载菜单栏
menubar = rc.LoadMenuBar('IDR_MENU')

这里的IDR_MENU是资源标识ID,不需要翻译,因此不做改变,而下面的代码:

info.SetVersion('1.0')
info.SetDescription('XRC i18n Demo')

'XRC i18n Demo'是描述性的文本,需要进行翻译,将需要处理为

info.SetVersion('1.0')
info.SetDescription(_('XRC i18n Demo'))

接着需要生成.pot(Portable Object Template),这是po的模板文件。在将来程序可能配置成其他语种,其他语言的po文件都从它而来。为了创建这文件,需要用到GNU gettext工具集中的xgettext。向xgettext传入些必要的信息,来创建.pot文件。

>xgetttext --output=test.pot test.py

我们将wxPython界面以XRC文件保存了,那里同样有要翻译的字符串需要提取。用XRCed工具将XRC生成python代码,勾选上'Generate gettext strings'项即可。将源文件和XRC生成的test_xrc.py文件一起处理,生成一个test.pot。

>xgettext --output=test.pot test.py test_xrc.py

将得到的test.pot另存为test.po文件,然后进行翻译编辑,在这过程中文件需要使用utf-8编码。将对应的英文翻译成中文,将charset更改为utf-8。

"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"

#: test.py:19
msgid "XRC i18n Demo"
msgstr "XRC 国际化示例"
...

.pot和.po这些文件都是文本文件,主要供翻译者使用。为了使程序在运行时能获取相关的翻译的内容,要进行所谓的编译过程,将文本文件转换为二进制文件.mo。这里用了gettext工具集中的另一程序msgfmt。

> msgfmt --output=test.mo test.po

因为windows下没有像linux像有公共存储.mo文件的目录,保持平台的迁移性,在应用程序本地目录下新建locale目录,用来存放编译过的.mo文件,然后将test.mo移动至locale目录。在完成这些步骤后,就转入代码方面的更改了。

wxPython代码更改

原先的代码只需要做小改动:

def OnInit(self):
    wx.Locale.AddCatalogLookupPathPrefix('locale')
    self.locale = wx.Locale(wx.LANGUAGE_CHINESE_SIMPLIFIED)
    self.locale.AddCatalog('test')
    import __builtin__
    __builtin__.__dict__['_'] = wx.GetTranslation

首先,增加了新的目录文件路径,这将使wxPython搜索这个目录,寻找匹配的.mo文件。接着创建wx.Locale对象,将其初始化为简体中文,这将对应于zh_CN。最后将wx.GetTranslation做了一全局映射,这样你在其他类中,比如示例中TestFrame也能使用_('xx')调用。这样wxPython的i18n工作就完成了,下面是翻译前后的界面截图。

wxpython

一些有益的讨论

.mo文件的查找目录

如果你将locale目录下的test.mo文件删除掉,然后将test.py中的wx.LANGUAGE_CHINESE_SIMPLIFIED改为wx.LANGUAGE_CHINESE,重新运行程序看看。发现界面变成了如下的繁体中文,但是菜单'档案'下的Exit还是英文。

wxzh

因为缺失.mo文件,但又指定wx.LANGUAGE_CHINESE,wxPython运行时使用了wxstd.mo文件。wxstd.mo有许多预编译好的常见字符串的对应关系,它随wxPython发布,在wx/locale下有许多语言版本的wxstd.mo。

对于wxPython会对待查目录"DIR"来搜索.mo文件,查找它下面的这些目录,(DIR/LANG/LC_MESSAGES;DIR/LANG;DIR),对于哪些是待查目录,各个系统下又有不同,在所有的平台上,LC_PATH环境变量指定的目录将成为待查目录,在Linux下/share/locale, /usr/share/locale, /usr/lib/locale, /usr/locale /share/locale以及当前目录将是待查目录。在上面我们已经用过AddCatalogLookupPathPrefix()函数,其作用就是增加自己的待查目录。

在示例程序中,将test.mo放在locale\zh_CN\LC_MESSAGES或者locale\zh\LC_MESSAGES同样是可行的。但是如果使用wx.LANGUAGE_CHINESE指定,则zh_CN目录将不可行,因为它只是特化目录,指简体中文,而zh目录同样适用。

工具链再讨论

gettext进行国际化是开源社区的主流方案,它也提供了许多实用工具供使用。上面提到了xgettext,msgfmt,还有msginit.exe,它将根据.pot文件创建新的.po文件,然后初始化一些元信息,像作者信息,项目,以及编码等,当然也可像上面的手工编辑。msgmerge.exe将两个.po文件进行合并。除了使用GNU Gettext工具集,也可使用随python发布的tool\i18n目录下pygettext.py和msgfmt.py,它们等同于上述的两个工具。

对于编辑.po文件,可以尝试一下Poedit,它提供了图形化的编辑环境,其他功能我就不清楚了。

posted @ 2008-07-15 20:21 len 阅读(76) | 评论 (0)编辑 收藏

在Windows下,许多网络程序的连接依赖于IE浏览器中的代理服务器的设置,IE浏览器的代理设置很可能设定了注册表中的全局网络连接配置。

我在IE浏览器中设置了代理,而使用Maxthon浏览网页。在写Python时,用了urllib2库,后来出现了下面的错误:

urllib2.URLError: <urlopen error (10061, 'Connection refused')>

先前这个程序是运行正确的,又直接用浏览器访问需要的网址,正常。通过排查,发现IE浏览器中设置了代理,而代理无效,而urllib2库使用其网络配置,因此无法连接。通过取消代理,程序连接正常。

还有一例是,刚才用Windows Live Writer检索日志,和发布日志时出错,分别显示如下的错误:

error err

这也是因为WLW使用IE的网络设置,造成的网络错误而显示的错误提示。

因此在设置了IE代理,并使用其他与网络相关的程序,要特别注意其是否对IE代理设置有依赖。像Maxthon等就可选择不使用IE代理配置的选项。

posted @ 2008-07-08 13:27 len 阅读(45) | 评论 (0)编辑 收藏

Windows Live Writer是写博客的利器,非常好用。只是对一些常见的html标签支持不足,比如没有预排文本标签<pre>之类的。在插入示例代码时,我不喜欢使用网上的那些高亮插件,它们增加了一些我感觉不友好的标签元素。我在写文章时,代码放在<pre>标签,然后使用自定义的code类,如果是一些屏幕输入输入文本,会用一个console类来进行说明。如果直接从源代码拷贝文本至html源文件时,xml文件的的<>"之类标签需要进行转义才可以。在这之前,我都需要手工将WLW切换到HTML模式进行创作,然后修改这些标签,非常麻烦。这样干了几次后,昨天决定自己写个WLW插件用。在搜索引擎的帮助下,找到Dflying Chen的 为Windows Live Writer开发插件——InsertSearchPageLink这篇文章,并在其参照完成了插件编写。

但在找到这篇文章之前,和编写插件的过程中,还是费了很多功夫。最早我认为写插件是需要下载SDK之类的软件,所以在Live Writer官方开发网站,Live Writer网,MSDN之类的找了个遍,看见是有SDK之类字样的下载,但弄不下来只有文档,根本不见其什么头文件,DLL之类的。在这花费了很多时间,最后才发现WLW插件的SDK是随WLW一起分发了,也就是WindowsLive.Writer.Api.dll之类的,这些dll 都随WLW主程序在一个目录中。还有一点是,现在WLW在中国是随Live套件一起发布的,因此路径由原来的C:\Program Files\Windows Live Writer变成了C:\Program Files\Windows Live\Writer,插件目录为Plugin。如果在网上发现有好用的插件,只需要将其发布的插件dll扔到这个目录就行了。

在开发中碰到图标资源不能成功加载,在Dflying Chen的文章中特意提到了图标资源需要是嵌入形式,我也按照其操作的,总以为是这里出现问题。后来花了一些时间,才找到总是的根源:自己在开发中更改了工程名,导致最后生成的程序集的名称与后来的命名空间名称不一致,图标路径就出错了。C#也只是这次用一下,这些都没有接触到。

昨天弄完自己的“插入Pre标记”插件后,想到自己写博客常需要截图,遂想再开发一个截图工具的。最早搜到了别人调用SnagIt搜件,不好用,因为SnagIt是商业软件,需要注册的。后来找到了picpick,小巧免费,非常实用。我想调用picpick的,但是在参照Insert SnagIt Screen Capture发现是用COM接口,而无奈picpick没有这样供开发使用的接口考虑,最终不可行。后来经过一些其他的尝试,都告失败。最后还是搜索帮了忙,找到了Screen Capture这个插件,原来有别人已完工了。

最后附上,我用这个新插件截的图,非常好用,只需一步:

tmp196

posted @ 2008-07-05 21:43 len 阅读(133) | 评论 (0)编辑 收藏

安装Cygwin

cgywin官方主页下载安装文件setup.exe,这只是一个网络安装包,体积很小。cgywin包含了许多GNU下的应用程序,真正安装时会根据你选择的组件,会自动去网上下载安装的。在国内最好使用镜像服务,这样速度会提高很多,建议去http://www.cygwin.net.cn/http://www.cygwin.cn/下载上述的安装包,并在安装进行到Choose A Download Site这个步骤时,选择合理的镜像。由于中国南北网速的差异,上述两个地址都尝试一下,看看哪个对你而言速度更快一些。

在进行到Select Packages这个步骤时,选择你需要包,建议如下:

  • Shells -> rxvt-unicode-x  强大的X终端,可用它替换windows下的cmd.exe
  • Net-> openssh  ssh客户端,可作putty的替换
  • Net-> inetutils  可选,包含一些基本的网络工具,如telnet,否则在cygwin下无法使用windows的telnet

cygwin安装时会自动进行包关联,在安装rxvt时,已自动将X server安装上了。

配置调整

启动cygwin,实际上是运行cgywin.bat批处理,它又调用了cmd.exe。我们将安装的rxvt作为默认终端,需要修改cygwin.bat。下面是我机子上的配置修改,请对应修改相应的路径。

@echo off
d:
chdir d:\Cygwin\bin
rxvt -e bash --login -i

调整rxvt观感,需要修改你用户主目录下的.Xdefaults文件,此文件在你选择的安装目录下的home\usrname下,在我的机子上是D:\Cgywin\home\len。若不存在,可在此目录下新建一个,修改内容如下:

Rxvt*background:        black
Rxvt*foreground:        #E2E6C7 
Rxvt*font:              9x16 
Rxvt*boldFont:          9x16 
Rxvt*scrollBar_right:   True
Rxvt*saveLines:         1024
Rxvt*geometry:          80x30
Rxvt*color0:            black
Rxvt*color1:            red
Rxvt*color2:            green   
Rxvt*color3:            yellow
Rxvt*color4:            blue
Rxvt*color5:            magenta
Rxvt*color6:            cyan    
Rxvt*color7:            white   
Rxvt*color8:            burlywood1
Rxvt*color9:            sienna1 
Rxvt*color10:           PaleVioletRed1  
Rxvt*color11:           LightSkyBlue    
Rxvt*color12:           white   
Rxvt*color13:           white
Rxvt*color14:           white   
Rxvt*color15:           white 

在cygwin下也是可以访问Windows下其他盘符的,如cd /cygdrive/c/windows,就转到了C盘windows目录下。这样对于在linux下工作的人说有点儿别扭,更希望是以cd /mnt/c/windows的mount方式来访问其他盘符。这需要修改注册表的选项,将HKLM\software\Cygnus Solutions\Cgywin\mounts v2下的子项cygdrive prefix更改为/mnt即可。

远程登陆Linux桌面

其实这里介绍的不仅仅适用于Linux,而是针对X Window的。X Widonw的介绍不进行赘述,但需要明确其中的服务器端和客户端的区别,在X Window的概念中服务器端是指你进行显示,输入输出的机器,也是接下来示例中的本机len-computer,IP为10.3.164.70,而客户端指的是进行远程登陆的机器auto-desktop,IP为10.3.164.74。

在局域网内最简单的方法是使用XDMCP连接,这时远程的机器启用xdmcp。那台机器运行着ubuntu-8.04,用gdm进行窗口管理,编辑/etc/gdm/gdm.conf-custom如下,其他版本的linux需找到对应的窗口管理的配置文件。

[security]
DisallowTCP=false

[xdmcp]
Enale=true

修改完后,在远程机器上重启服务,$sudo /etc/init.d/gdm restart。接下来本机启动cgywin,转到X目录下,运行Xwin.exe,使用 -query指定远程的linux机器的ip即可。

Len@len-computer /usr/X11R6/bin
$ cd /usr/X11R6/bin

Len@len-computer /usr/X11R6/bin
$ Xwin -query 10.3.164.74

这里会出现如下面图示的窗口,提示输入用户名和密码。另再附一张在登陆成功后,我在本地执行远程操作的截图。

login

cygwinX

如果你需要连接的远程机器比较固定,可以修改本地机器d:\cgygin\usrX11R6\bin\startxdmcp.bat中的REMOTE_HOST值为你需要连接机器的IP,这个批处理设置了一些有用的环境变量值。或许你需要创建一个桌面的快键方式,这样每次点击,就直接连接到远程机器了。

不引入桌面环境

可能有时候只需要将某个需要X服务的远程应用程序引入到本地桌面显示,而不需要启动像上面的GNOME或者KDE等庞大的桌面环境。这样做比较适合喜欢终端操作的人,我就常常终端敲命令,然后将gvim,openoffice这些从远程导入到本地操作。

找到d:\cgywin\usr\X11R6\bin\startwin.bat,将%RUN% xterm -e /usr/bin/bash -l注释掉,因为我们己经有了rxvt,不需要一个新的xterm终端了,执行该批处理文件,就会在本机运行X server。启动cgywin,用ssh登陆到远程机器上,执行如下命令,导出DISPLAY环境变量和运行你感兴趣的程序。

auto@Auto-desktop:~$ export DISPLAY=10.3.164.70:0.0
auto@Auto-desktop:~$ gvim&
[1] 22652
auto@Auto-desktop:~$ oowriter&

其中环境变量DISPLAY中的:0.0部分表示X server的display和screen。display指运行着X server实例。如果使用TCP/IP连接,表示的是端口6000+display号做为连接。screen代表X server上的不同输出设备。我在例子中执行gvim和openoffice.org-writer,运行的效果可看下面的截图。在ubuntu上运行着的gvim和openoffice都在我本机10.3.164.70上显示了,并且可操作。

screen

有用的链接

Cgywin/X FAQ 在碰到一些操作问题时,不妨先看看这份FAQ

使用cygwin X server实现Linux远程桌面 easwy介绍了KDE环境下的配置,部分受此启发

使用rxvt做为cygwin终端 碰到rxvt中文显示问题时,或许有帮助

posted @ 2008-07-03 21:55 len 阅读(176) | 评论 (0)编辑 收藏

QQ在许多公司内部被禁止使用,为了能使用QQ,稍微懂点儿计算机的人都知道用代理。QQ提供了socket和http代理这两种功能,socket代理功能强大,但一般公司对外允许连接的端口号比较有限,难以利用。大多数公司是允许连接外部的80端口的,这样使用QQ的http代理是可行的。但是找到能用的QQ代理有点儿麻烦,因此下面的Python代码提供了自动进行QQ代理验证的功能。

import urllib2
import socket
import re

f = urllib2.urlopen('http://www.proxycn.com/html_proxy/http-1.html')
content = f.read()
f.close()
ipPattern = re.compile(r'(\d+\.\d+\.\d+\.\d+):80')
ipList = ipPattern.findall(content)
print ipList
requestData = "CONNECT http.tencent.com:443 HTTP/1.1\x0d\x0a"
requestData += "Accept: */*\x0d\x0aContent-Type: text/html\x0d\x0a"
requestData += "Proxy-Connection: Keep-Alive\x0d\x0a"
requestData += "Content-length: 0\x0d\x0a\x0d\x0a"
for ip in ipList:

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    try:
        s.connect((ip,80))
        s.send(requestData)
        data = s.recv(64)
        if data.find("200 Connection established")!= -1:
            print ip, 'good'
            # A vailable proxy is found once, then exit the program
            s.close
            exit(0)
        else:
            print ip, 'bad'
    except socket.error:
        print ip, 'dead'
    finally:
        s.close

程序在找到一个可用的QQ代理后退出,用good标识。另两种代理服务器的状态是dead,说明本地无法连接到代理服务器,或是bad,能与代理服务器建立连接,但是代理不能与QQ服务器通讯。

代码思路

通过代理中国获取到80端口的代理服务器列表,使用了urllib2模块获取页面数据,然后正则表达式解析出80端口的IP地址存入list中。接下来的几行代码简单,但是很重要,使用较为底层的socket对象,构造合适的数据包通过代理,请求与QQ服务器连接,通过读取的返回数据包来验证连接是否能建立。

这里主要涉及到了HTTP协议的CONNECT的概念,很多人可能认为http代理只是为web浏览提供服务,其实CONNECT方法允许允许用户建立TCP连接到任何端口,这意味着代理不仅可用于HTTP,还可用于FTP,QQ等其他协议。只是网上提供CONNECT方法的代理服务器比较少,我有时候扫了一大堆,也没有找到一个可用的代理。反过来说,有时候你找到的能浏览网页的http服务器,未必能用在QQ上,QQ需要的是能CONNECT的代理。网页浏览一般只使用HTTP协议的GET或POST方法,提供这两种方法的服务器就多了。

了解了代码的原理,稍做改动,就可以用于其他类型的代理的验证了,需要的是一些基本网络知识和数据报的发送和接收。

posted @ 2008-07-02 22:13 len 阅读(107) | 评论 (0)编辑 收藏

Subversion的属性是非常好用的功能,它将一些工作自动化,实现为受版本控制的源文件添加元信息的作用。属性是外部不可见的,可以简单认为是附加上在文件上的信息,和文件大小之类的信息是一样的,只不过他是通过subversion来管理的。属性的名称和值可以是你希望的任何值,限制就是名称必须是可读的文本,并且最好的一点是这些属性也是版本化的,就像你的文本文件内容,你可以像提交文本修改一样修改、提交和恢复属性修改,当你更新时也会接收到别人的属性修改—你不必为适应属性改变你的工作流程。

Subversion保留了一组名称以svn:开头的属性,来预定义一些有用的功能。比如你常会看到一些人的源代码底部有像下面之类标识的文字:

$Id: main_window.py 68 2008-06-30 02:05:05Z Len $

这就使用了Subversion 中的 svn:keywords的自动属性,它让将发生在源代码中的一些属性的变化自动地更新到源代码中。这行字的意思是表示,main_windows.py 这个源代码文件最后被用户 len 更新于 2008-6-30 02:05:05Z,修订版本号为 68。要实现这样的自动更新,你只要对需要这样属性的文件上使用下面这行指令。

> svn propset svn:keywords "Id" main_window.py

或者使用TortoiseSVN中的Properties的操作按钮,方便地增加新的属性。接着需要在源代码文件中需要 Subversion 进行自动更新的地方插入 $Id$ 这样的 Keyword,那么在你下次进行提交更新时,该$Id$ 就会被 Subversion 自动替换为$Id: main_window.py 68 2008-06-30 02:05:05Z Len $ 这样的格式。
Subversion 中可以使用的Keyword 包括下面这些:

  • Id
    上面介绍过的综合的格式
  • LastChangedDate
    最后被修改的时间,缩写为 Date。
  • LastChangedBy
    最后修改该源代码文件的用户名,缩写为 Author。
  • LastChangedRevision
    最后修订的版本号,缩写为 Revision。

如果想每次向Subversion服务器提交文件修改时,都要设置文件的属性,则需要进行Subversion配置的修改。配置文件在你用户的主目录下,在Windows下应类似于C:\Documents and Settings\Len\Application Data\Subversion\config文件,Len是Windows用户名,注意Application Data是隐藏文件夹,需要显示全部文件才能看到。接着如下相应的修改,对你想要处理的文件做配置。

enable-auto-props = yes   
[auto-props]   
*.c = svn:keywords=Id   
*.py = svn:keywords=Id 

对于开源项目,常见其源文件头部有着版权声明的文本,这些操作大多也是通Subversion的属性功能来完成的,有关更详细的介绍和操作指南,可参见Subversion中文手册中的属性章节。

posted @ 2008-06-30 12:06 len 阅读(82) | 评论 (0)编辑 收藏

这个类表示在单独的控制线程中运行的活动。有两种方法可以指定这种活动,给构造函数传递回调对象,或者在子类中重写run() 方法。其他方法(除了构造函数)都不应在子类中被重写。换句话说,在子类中只有__init__()run()方法被重写。

一旦线程对象被创建,它的活动需要通过调用线程的start()方法来启动。这方法再调用控制线程中的run方法。

一旦线程被激活,则这线程被认为是'alive'(活动)。当它的run()方法终止时-正常退出或抛出未处理的异常,则活动状态停止。isAlive()方法测试线程是否是活动的。

一个线程能调用别的线程的join()方法。这将阻塞调用线程,直到拥有join()方法的线程的调用终止。

线程有名字。名字能传给构造函数,通过setName()方法设置,用getName()方法获取。

线程能被标识为'daemon thread'(守护线程).这标志的特点是当剩下的全是守护线程时,则Python程序退出。它的初始值继承于创建线程。这标志用setDaemon()方法设置,用isDaemon()获取。

存在'main thread'(主线程),它对应于Python程序的初始控制线程。它不是后台线程。

有可能存在'dummy thread objects'(哑线程对象)被创建。这些线程对应于'alien threads'(外部线程),它们在Python的线程模型之外被启动,像直接从C语言代码中启动。哑线程对象只有有限的功能,它们总是被认为是活动的,守护线程,不能使用join()方法。它们从不能被删除,既然它无法监测到外部线程的中止。

class Thread(group=None, target=None, name=None, args=(), kwargs={})

构造函数能带有关键字参数被调用。这些参数是:

group 应当为 None,为将来实现ThreadGroup类的扩展而保留。

target 是被 run()方法调用的回调对象. 默认应为None, 意味着没有对象被调用。

name 为线程名字。默认,形式为'Thread-N'的唯一的名字被创建,其中N 是比较小的十进制数。

args是目标调用参数的tuple,默认为()。

kwargs是目标调用的参数的关键字dictionary,默认为{}。

如果子线程重写了构造函数,它应保证调用基类的构造函数(Thread.__init__()),在线程中进行其他工作之前。

start()
启动线程活动。

在每个线程对象中最多被调用一次。它安排对象的run() 被调用在一单独的控制线程中。

run()

用以表示线程活动的方法。

你可能在子类重写这方法。标准的 run()方法调用作为target传递给对象构造函数的回调对象。如果存在参数,一系列关键字参数从argskwargs参数相应地起作用。

join([timeout])
等待至线程中止。这阻塞调用线程直至线程的join() 方法被调用中止-正常退出或者抛出未处理的异常-或者是可选的超时发生。

timeout参数未被设置或者不是None,它应当是浮点数指明以秒计的操作超时值。因为join()总是返回None,你必须调用isAlive()来判别超时是否发生。

timeout 参数没有被指定或者是None时,操作将被阻塞直至线程中止。

线程能被join()许多次。

线程不能调用自身的join(),因为这将会引起死锁。

在线程启动之前尝试调用join()会发生错误。

getName()
返回线程名。
setName(name)
设置线程名。

这名字是只用来进行标识目的的字符串。它没有其他作用。多个线程可以取同一名字。最初的名字通过构造函数设置。

isAlive()
返回线程是否活动的。

大致上,线程从 start()调用开始那点至它的run()方法中止返回时,都被认为是活动的。模块函数enumerate()返回活动线程的列表。

isDaemon()
返回线程的守护线程标志。
setDaemon(daemonic)
设置守护线程标志为布尔值daemonic。它必须在start()调用之前被调用。

初始值继承至创建线程。

当没有活动的非守护线程时,整个Python程序退出。

参见:Python Library Reference

posted @ 2008-06-24 16:54 len 阅读(114) | 评论 (0)编辑 收藏

介绍

cURL是一个利用URL语法的文件传输工具,是基于libcurl的前端命令行工具。它支持很多协议:FTP, FTPS, HTTP, HTTPS, GOPHER, TELNET, DICT, FILE 以及 LDAP。 它同样支持HTTPS认证,HTTP POST方法, HTTP PUT方法, FTP上传, kerberos认证, HTTP上传, 代理服务器, cookies, 用户名/密码认证, 下载文件断点续传, 上载文件断点续传, http代理服务器管道( proxy tunneling), 甚至它还支持IPv6, socks5代理服务器,通过http代理服务器上传文件到FTP服务器等等,功能十分强大。

除了使用curl命令行直接进行相关的网络操作,你也可以自由地使用libcurl,它是用C语言编写的,可以绑定到众多的编程语言中,如C,C++,PHP,Python,Perl,Java等等。你可以很方便地利用libcurl,在程序中进行一些网络传输工作,来代替一些语言的内置,使你的知识可重用。在Unix工作环境下,你可以用curl代替wget和ftp等工具,并能将这种学习经验迁移到将来使用libcurl来完成一些自动化任务。

curl是瑞典curl组织开发的,可以通过http://curl.haxx.se/来获取更详细的信息和下载文件。

curl命令行工具使用

curl太强大了,只能对其HTTP的部分作一简单的介绍,其他选项可以参见其附带的手册。它的后端库的使用也非常方便,主要也是在选项设置上,跟命令行基本无异。

用法

curl [选项] [URL...]

URL 语法

URL语法是跟协议相关的,具体细节可参见RFC 3986
可以指定多个URLs或者部分URL地址,通过花括号{}进行分割:
http://site.{one,two,three}.com
或者用[]使用字母序:
ftp://ftp.numericals.com/file[1-100].txt
ftp://ftp.numericals.com/file[001-100].txt (有前导零)
ftp://ftp.letters.com/file[a-z]].txt

当前序列嵌套不被支持,但是还是可以使用下列的样式:
http://any.org/archive[1996-1999]/vol[1-4]/part{a,b,c}.html
可以在命令行指定任意数量的URLs,它们将以指定的顺序被取回。

从curl7.15.1开始指定可以范围步长,所以可以得到第n个数或字母:
http://www.numericals.com/file[1-100:10].txt
http://www.letters.com/file[a-z:2].txt

如果使用了protocal://前缀,curl会将尝试你想使用的协议。它默认使用HTTP,但是其他一些协议也常被用作主机名。比如说,以"ftp"打头的主机名,curl会假定你想使用ftp协议。

Curl会尝试对多文件传输使用重连接,可以使从同一服务器获取很多文件时,不会进行多次的连接。这种做法改进了速度,当然这只会在同一命令行中指定的文件启用,而不会在独立的Curl调用时使用。

进度指示器

curl通常在操作时会显示一个进度指示器,来指明当前的传输量,传输速度和预计的剩余时间等等。

但是,即然curl默认将数据显示在终端,如果你调用curl进行操作,它会将数据打印到终端上,这时它会禁用掉进度指示器,否则这些会将输出信息搞乱掉。

如果在进行HTTP的POST或PUT请求时,你想将输出重定向到文件中,可以使用shell的重定向符(>),或者类似的-o[file]选项。

但是在FTP上传并不会这样,这些操作不会将数据插入到终端中。

如果想使用进度栏,而不是常规的指示器,那么-#会非常有帮助。

常用的HTTP选项

-A/--user-agent<agent string>
(HTTP)指定用户代理字符串发送给HTTP服务器。如果这个字段没有被设为"Mozilla/4.0",某些CGIs将不会正常工作。如果在字符串中存在空白字符,需要用单引号标识。这个字段值也可用-H/--header选项进行设置。
如果这选项被多次设置,最后的设置将起作用。

-b/--cookie<name=data>
(HTTP)将data作为cookie传给HTTP服务器,这数据当然是在使用了"Set-Cookie:"后,先前从服务端接收到的。这数据应是"NAME1=VALUE1;NAME2=VALUE2"的格式。
如果没有"="字符,它将会当作先前存储cookie行的文件名,如果它能被匹配的话。使用这选项,也能激活"cookie parser",它使curl记录传入的cookies数据。将它与-L/--locaion选项组合将会更加便利。被读取cookie的文件格式应当是文本HTTP头或者Netscape/Mozilla cookie文件格式。
注意:被-b/--cookie指定的文件只能作为输入使用。没有cookie会存储在这文件中。为了存储cookie,应使用-c/--cookie-jar选项或者直接将HTTP头输出到文件中,用-D/--dump-header选项。这选项可以设置多次,但是只有最后一个起作用。

-connect-timeout<seconds>
以秒计的最大超时,用于进行服务器连接时。这只在连接阶段起作用,一旦curl连接建立,这选项将不再起作用。

-c/--cookie-jar<file name>
指定在完成一系列操作后,需要将全部的cookie信息保存到哪个文件中。Curl会将先前读取的cookie的信息和从服务器返回的信息一起保存。如果没有cookie信息,则不会进行写文件。cookie信息的文件将与Netscape cookie文件格式保存。如果文件名被设置为'-',则将cookie打印至终端。
注意:如果cookie-jar不能被创建写入,整个curl操作也不会失改,甚至不会向你报告错误.使用-v将会得到警告显示,但也只能在可能导致发生致命错误的情况才会显示。

--create-dirs
这与-o选项配合使用,curl会在需要时建立本地文件夹结构。这选项会创建在-o选项中涉及到的文件夹。如果-o选项中的文件名没有使用到文件夹,或者所需的文件夹已经存在,则不会有文件夹创建。

-D/--dump-header<file>
将协议头写到指定的文件中。当你想存储HTTP站点发给你的数据时,这选项非常有用。在协议头中的cookie将来可以用curl的另外调用来进行读取,那就是-b/--cookie选项。但是-c/--cookie-jar选项将会是更好的存储cookie信息的方法。
当使用FTP协议时,ftp服务器的应答信息将相应地当作成协议头,然后被存储。

-p/-proxytunnel
当HTTP代理被设置后(-x/--proxy),选项会使不是HTTP协议的传输试图通过代理隧道,而不是表现得HTTP类似的操作形为。代理隧道的方法是通过HTTP服务器直接使用CONNECT请求,让代理直接连接到curl隧道所请求的远程端口号的方式来实现的。

-o/--output<file>
将输出信息打印到文件中,而不是终端。可使用{}或者[]取回多个文档,可在file指定格式中的'#'跟一数字,这样这变量将会由取回的URL字符串所取代。如下:
curl http://{one,two}.site.com -o "file_#1.txt"
如果有多个变量,可以写成下面的样子:
curl http://{site.host}.host[1-5].com -o "#1_#2"
你可对任意数量的URL使用同样多的这个选项

-x/--proxy<proxyhost[:port]>
使用指定的HTTP代理,如果端口号没有被指定,默认为1080.
这选项会覆盖环境变量中代理服务器的设置。如果环境变量中设置了代理,可将proxy设置为空字符串,来覆盖环境变量中的设置。
注意:所有通过HTTP代理的操作都会自动转化为HTTP协议。这意味着一些特定协议的操作将会变得无效。这不会有问题,如果在设置了-p/--proxytunnel选项来通过代理隧道进行操作。

简单示例

获取cppblog首页,打印至终端

>curl http://www.cppblog.com
重定向,保存到文件cppblog.html
>curl http://www.cppblog.com
作用同上,使用选项
>curl -o baidu.html http://www.baidu.com
使用http代理,可指定IP和端口
>curl -x 202.127.98.43:80 -o baidu.html http:www.baidu.com
在访问一些论坛时,常常要求启用cookie,因为这些网站需要启用cookie来记录sessioin信息,这时需要选项-D,将cookie信息保存起来
>curl -o cpp.html -c len@cppblog.com[1].txt http://www.cppblog.com

先前保存的cookie信息返回给网站,这通常会传回你的一些用户信息。
>curl -o cpp.html -c len@cppblog.com[2].txt -b len@cppblog.com[1].txt http://www.cppblog.com
posted @ 2008-06-21 16:33 len 阅读(341) | 评论 (0)编辑 收藏
仅列出标题  下一页

<2008年9月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

常用链接

留言簿(1)

随笔分类

随笔档案

搜索

  •  

最新评论

阅读排行榜

评论排行榜