标签归档:python

用程序生成word文档(DOC)

很多程序都支持导出PDF文档,不过如果需要对导出文档进行编辑PDF就显得不那么方便了。就国内环境而言,导出word文档对有编辑需求的文档而言更为合适。
由于我使用python,因此这里只讨论python下可用的方案。目前找到的解决方案主要有下面几种

  • python-docx
    目前能找到支持word格式的库非常的少,就python而言只找到 python-docx 算是相对可用的解决方案。python-docx 的功能非常的弱,有很多的限制,比如不支持模板等。如果想生成复杂文档那就无能为力了。
  • POD
    POD是Appy框架的一部分,可使用ODF (Open Document Format)文件做为模板,并输出ODF格式的文件,并可调用LibreOffice将生成的文件转换成DOC等格式。相比python-docx,POD用于生成更为复杂的文档。但如果你需要动态生成一些复杂表格,POD可能会有些问题。
  • unoconv
    unoconv是个文档转换工具,可调用LibreOffice对文档格式进行转换。unoconv可将HTML转换为DOC格式。因此可先生成HTML,然后再将HTML转换为DOC。生成HTML对广大的WEB开发者而言无疑是轻而易举的,这也是我最终选择的方案。不过要注意的是用unoconv将HTML转换成DOC,遍地是坑-_-!。

    • 只支持有限的HTML语法。很多CSS语法根本就不支持,看到的和转换出来的效果完全不一样。解决办法:在LibreOffice中编辑文档,然后保存成HTML,然后对保存的HTML进行编辑。
    • unoconv的-t参数可传入.ott格式的文档模板。默认情况下LibreOffice转换出的表格的行高远大于文字的高度,更糟糕的是文字还是顶对齐,非常不美观。编辑个空文档,然后保存为.ott,转换的时候指定模板文件可解决该问题。
    • 生成的文档的左右边距不一致。恩…,这个我还没有找到解决办法。

让你的python程序同时兼容python2和python3

python邮件列表里有人发表言论说“python3在10内都无法普及”。在我看来这样的观点有些过于悲观,python3和python2虽然不兼容,但他们之间差别并没很多人想像的那么大。你只需要对自己的代码稍微做些修改就可以很好的同时支持python2和python3的。下面我将简要的介绍一下如何让自己的python代码如何同时支持python2和python3。

  • 放弃python 2.6之前的python版本
    python 2.6之前的python版本缺少一些新特性,会给你的迁移工作带来不少麻烦。如果不是迫不得已还是放弃对之前版本的支持吧。
  • 使用 2to3 工具对代码检查
    2to3是python自带的一个代码转换工具,可以将python2的代码自动转换为python3的代码。当然,不幸的是转换出的代码并没有对python2的兼容做任何的处理。所以我们并不真正使用2to3转换出的代码。执行 2to3 t.py 查看输出信息,并修正相关问题。
  • 使用python -3执行python程序
    2to3 可以检查出很多python2&3的兼容性问题,但也有很多问题是2to3发现不了的。在加上 -3 参数后,程序在运行时会在控制台上将python2和python3不一致,同时2to3无法处理的问题提示出来。比如python3和python2中对除法的处理规则做过改变。使用-3参数执行4/2将提示 DeprecationWarning: classic int division 。
  • from __future__ import
    from __future__ import”后即可使使用python的未来特性了。python的完整future特性可见 __future__ 。python3中所有字符都变成了unicode。在python2中unicode字符在定义时需要在字符前面加 u,但在3中则不需要家u,而且在加u后程序会无法编译通过。为了解决该问题可以 “from future import unicode_literals” ,这样python2中字符的行为将和python3中保持一致,python2中定义普通字符将自动识别为unicode。
  • import问题
    python3中“少”了很多python2的包,在大多情况下这些包之是改了个名字而已。我们可以在import的时候对这些问题进行处理。
try:#python2
    from UserDict import UserDict
    #建议按照python3的名字进行import
    from UserDict import DictMixin as MutableMapping
except ImportError:#python3
    from collections import UserDict
    from collections import MutableMapping
  • 使用python3的方式写程序
    python2中print是关键字,到了python3中print变成了函数。事实上在python2.6中已经带了print函数,所以对print你直接按照2to3中给出的提示改为新写法即可。在python3中对异常的处理做了些变化,这个和print类似,直接按照2to3中的提示修改即可。
  • 检查当前运行的python版本
    有时候你或许必须为python2和python3写不同的代码,你可以用下面的代码检查当前系统的python版本。
import sys
if sys.version > '3':
    PY3 = True
else:
    PY3 = False
  • six
    six 提供了一些简单的工具用来封装 Python 2 和 Python 3 之间的差异性。我并不太推荐使用six。如果不需要支持python2.6之前的python版本,即使不用six也是比较容易处理兼容性问题的。使用six会让你的代码更像python2而不是python3。

python3的普及需要每位pythoner的推动,或许你还无法立即升级到python3,但请现在就开始写兼容python3的代码,并在条件成熟时升级到python3。
注:

编程语言们各自的哲学

曾有同事打算将ZOPE和PLONE啃下,我是不建议的。同事说我不够开放,对自己不喜欢的技术都很排斥。我承认,每个人都会有自己的偏好。但我不赞成使用ZOPE恰恰不是因为偏好问题,我也不会因个人偏好而建议采用或不采用某项技术。
在我看来ZOPE是一个很变扭的技术。ZOPE引入了接口/容器等概念,给人感觉ZOPE在很多方面都在有意的模仿JAVA。Python和JAVA在语言哲学方面有着比较大的差异,试图以Java的方式来做一个Python的WEB开发框架无疑是有些别扭的。如果ZOPE真的学的特别象,那我为什么不干脆直接使用Java?
这世界上存在各种编程语言,每种编程语言都有着自己的特点,正是这些差异满足了各类人的不同需求。这些编程语言都有着自己最核心的思想,这个核心思想就是所谓的“哲学”。没有自己“哲学”的编程语言是无法在这个世界上存活的。有些编程语言看上去问题很多,却很流行。或许它的那些问题也正是它流行的原因。

PHP

PHP的使用门槛非常的低,而且通常用PHP写出来的东西代码都不是那么的“漂亮”。于是有些人将PHP看成是业余程序员用的东西。然而就是这么一个看似不怎么专业的东西统治了大半个互联网。PHP的“哲学”是“quick and dirty”。在一定程度上beauty和quick并不容易并存。PHP将quick和简单作为第一要求,代码的漂亮退居第二。dirty的代码并不容易维护,所以通常在系统在复杂后,复杂业务逻辑功能将交由其他技术实现。PHP则安心做着自己表现层的事。

Java

有人说Java是给笨人用的语言。这话虽然很难听,不过在一定程度上这还真就是Java的哲学。Java充分利用语言特性和IDE等自动化工具来避免程序员犯错,让人海战术成为可能。对于大多Java项目只需要少数的牛人来设计系统构架和主要接口,下面的具体实现用“笨人”来做就可以了。

Python

python的哲学是“quick and clean”。在一定程度上说python确实非常clean也很quick。不过python的clean可让也让python变的有些平庸。python号称什么都能做,却又没在哪个领域特别突出。

Ruby

Ruby强调人文关怀,编程是一件有乐趣的事,你可以按照自己喜欢的方式去使用ruby。相对而言ruby可能更容易发挥个人的创造性,但在团队协作时则容易遇到麻烦。

迁移到python3

python3自2008发布以来,已经历经了快4个年头。python3发布初期的速度慢,第三方开发库少的问题已得到了很好的改善。似乎已经没有太多的理由死抱着python2不放了。
考虑到目前的大多系统还都跑在python2.x上,直接迁移到python3还是有些冒进。最理想的方式是新代码都可实现python2&python3的兼容,日后可以平滑升级。下面的一些资料可以帮助你实现到python3的迁移。

发布一个Django的论坛系统LBForum(开源、带演示)

简介

LBForum 用django开发的论坛系统,演示地址为:http://vik.haoluobo.com/lbforum/
项目的地址为:http://github.com/vicalloy/LBForum
界面部分抄的 FluxBB(一个开源的PHP论坛 http://fluxbb.org/ )。
虽然Django写的论坛也不少,不过还真没什么好用的。
大多Django论坛都是独立的app,而且不少还缺模板,想我这样有经验的Django用户要跑起来都觉得麻烦,其他普通用户就更别说了。
LBForum主要注重部署的方便性和易用性,功能方面目前还比较简单。
LBForum一开始就是以整站的形式提供,所以以LBForum做为基础项目进行二次开发是很容易的。
同时LBForum的开发尽量遵照Django可复用app原则,因此即使需要将LBForum做为独立的app集成到其他项目也并不会太难。

主要功能

目前功能还比较简单,而且还有些小问题有待修正。

  1. 论坛分类,分版块
  2. 发帖,回帖
  3. BBCode支持
  4. 置顶贴
  5. 使用django admin提供论坛管理功能

用开发服务器把LBForum跑起来

  1. 先把代码down下来。LBForum托管在github上,http://github.com/vicalloy/LBForum 。如果你没有安装git,你可以直接用界面右上方的download
    source功能下载代码。
  2. 运行\scripts\create_lbforum_env.py初始化lbforum的python虚拟环境。该脚本会自动创建一个python的虚拟环境并使用easy_install安装对应的依赖包,同时将一些依赖包解压到对应的目录中。
    注:django使用的是svn版本,所以机器上必须要安装有SVN,不然脚本会运行失败。如果因为由于svn的问题导致脚本运行失败,可以运行lbforum_env.bat进入lbforum环境,手动安装django的svn版本。
  3. 环境初始化好后,运行lbforum_env.bat进入lbforum环境
  4. 运行%mg% syncdb初始化数据库
  5. 运行%mg% runserver启动django开发服务器
  6. 进入admin,创建论坛分类和版块
  7. 进入版块发帖

LBForum的目录结构说明

|+lbforum_env/#lbforum运行的python虚拟环境,运行create_lbforum_env.py后自动创建
|+requirements/#lbforum用的第三方库和app,运行的时候会将该目录加到python路径
|~scripts/#工程相关脚本
| |-create_lbforum_env.py#初始化python虚拟环境,并自动安装easy_install/django依赖库
| |-helper.py#提供其他脚本所需的辅助函数
| `-lbforum_env.bat*#启动lbforum运行的虚拟环境及,并为lbforum的manage.py提供快捷方式%mg%,比如初始化数据库%mg%
syncdb
|~sites/#站点配置/模板/静态文件
| `~default/#默认站点
|   |+static/#静态资源文件,如css等
|   |+templates/#Django模板目录
|   |+templates_plus/#Django模板目录,用户将自己重写过的目标放到该目录
|   `-……
|~src/#django的app目录
| |+account/#account相关app。具体站点通常会对用户中心进行定制,所以该app在实际应用中很可能需要针对实际情况进行修改。
| |+djangohelper/#一些django的辅助函数等,
| |+lbforum/#lbforum的主app,论坛功能都在改app中
| |+lbregistration/#registration app的lbforum扩展,主要去掉邮件地址认证功能
| |+onlineuser/#显示在线用户的app(可复用的django app,可脱离lbforum单独使用)
| `+simpleavatar/#头像功能的app(可复用的django app,可脱离lbforum单独使用,依赖djangohelper)
|+tools/#工程用到的辅助工具,目前只有一个virtualenv的脚本

注:

  1. 由于计划在以后做i18n,所以目前只提供英文界面
  2. django的错误提示是显示在字段后面,fluxbb的错误全部都显示在表单前面。由于模板没有调好,所以目前按照fluxbb的方式显示错误,所以错误显示有些不太正常。
  3. bbcode的输入框本想做成自适应大小的,不过也调得有些问题,所以现在输入框的大小固定。
  4. 文档… ,感觉好难写-_-,目前文档不全(项目中没有带任何的文档),日后补上。
  5. 应用程序的目录结构主要查看pinax
  6. simpleavatar模块部分代码来自django-avatar
  7. 依赖包除用easy_install在线安装的外,尽量使用zip包的方式附带在项目中,减少安装依赖包的困难。
  8. 远程部署脚本计划使用fabric,但fabric本身安装比较麻烦,所暂未处理。
  9. 项目最早放在googlecode,不过感觉github的功能更强些,所以移了过去。

SourceForge使用Python、TurboGears、MongoDB……来重构网站

pycon2010上关于SF网站重构的演讲,里面介绍了SF重构的技术选型及原因。在我看来SF用的东西还真的很GEEK。
主要用到的技术有Python、TurboGears2MongoDBJinja*、RabbitMQ,服务器用的是LigHTTPd和Nginx。

  • TurboGears2(为什么不的Django?)
    pdf中也有谈到此前也用到过django,而且有很不错的体验,但对SF的改造来说TG更为合适。SF有着上10年的历史,要完全抛弃原有的东西自然不现实,此次的网站重构并不是完全的重写。TG可以很容易的剥离掉不需要用到的东西,同时TG可以很好的同其他WSGI中间件配合工作。
  • MongoDB
    MongoDB是一个非关系的分布式数据库(NoSQL数据库),最大的优势快。由于这东西足够快,所以连web2.0网站常用的memcached也省掉了。(注:NoSQL数据库介绍可以参考 NoSQL数据库探讨之一 - 为什么要用非关系数据库)
  • Jinja*
    Django的模板很棒,但速度不怎么快,而且完全不支持任何嵌入式代码。Jinja和Django的模板长得非常的象,而且解决了上面的两个问题。(注:文档里说前台用的是PHP,所以不清楚是否有部分用到Jinja)
  • RabbitMQ
    用Erlang写的中间件,进行前后台的消息通信。SF的前台界面呈现,依旧使用的PHP,前后台通信用的就是这东西。

Whoosh性能

早些时候就在google到Whoosh和xapian的性能对比文章,只是由于文章被墙,今天才翻墙看到。
文章是xapian作者写的。就文章里的对比结果来看,whoosh和xapian的性能差距还是比较明显。索引和搜索的速度有近4倍的差距,在full cache情况下的性能差距更是达到了60倍。
除算法原因外,whoosh的纯python定位也决定了whoosh很难达到其他c/java的搜索引擎库的速度。
当然,whoosh的优势是易用性,在考虑性能的情况下whoosh不是首先。
注:Xapian performance comparision with Whoosh

纯python的全文搜索组件Whoosh

haystack 是 django 全文搜索的一个中间件,可以粘合 django 应用和 solr、xapian、whoosh 全文搜索引擎。

solr和xapian是早就知道的,Whoosh就没听过了。简单的了解后感觉这东西还是非常不错的。whoosh是一个纯python实现的全文搜索引擎。对python应用而言,whoosh的纯python实现,使whoosh的集成会容易很多,而且扩展起来也会容易很多。

下面是对Whoosh官方简介的翻译

原文地址http://whoosh.ca/wiki

Whoosh: 高效的纯python全文搜索组件

Whoosh是一个纯python实现的全文搜索组件。Whoosh不但功能完善,还非常的快。

Whoosh的作者是MattChaput,由Side Effects Software公司开发。项目的最初用于Houdini(Side Effects Software公司开发的3D动画软件)的在线帮助系统。Side Effects Software公司将该项目开源。

主要特性

  • 敏捷的API(Pythonic API)。
  • 纯python实现,无二进制包。程序不会莫名其妙的崩溃。
  • 按字段进行索引。
  • 索引和搜索都非常的快 — 是目前最快的纯python全文搜索引擎。
  • 良好的构架,评分模块/分词模块/存储模块等各个模块都是可插拔的。
  • 功能强大的查询语言(通过pyparsing实现功能)。
  • 纯python实现的拼写检查(目前唯一的纯python拼写检查实现)

为啥选择Whoosh

  • 纯python实现,省了编译二进制包的繁琐过程。
  • python代码比java更容易读懂,而且用起来也更方便。(翻者注:这个容易引发口水)
  • 在很多时候易用性比单纯的最求速度更重要。

Whoosh从其他的开源搜索引擎中获取了大量的灵感。 基础构架参考Lucene,使用KinoSearch的索引算法,部分评分算法来自Terrier,英文的词语态变化来自Minion.

初次尝试翻译较长的文章

以前也翻译过一些东西,不过都是非常短的文字。今天在网上看到一篇关于unladen swallow(Google的python实现)的文章,于是尝试对其进行翻译。

翻译东西确实不是一件容易的事。外文文章要读懂很容易,你只想要关注其中的重点即可,对于一些不重要的地方即使你没读懂也没关系。在翻译的时候你很容易的就会陷入了原作者的语言习惯,但外文和中文的语言习惯还是有很大的差别。其中语言习惯的差别不仅仅表现在句式结构上,还会贯穿在整片文字的语言组织上。所以如果你是按句翻译,那不管你如何组织语言,依旧会读起来很拗口。

除技术因素外,翻译还是一个很考验耐心的活。一篇可以在几分钟内读完的文章翻译起来得花几个小时。

虽然翻译得比较糟糕(自己都不想再读一遍),不过总算翻译完了,如果哪天有空就再休整一下,至少不要读得这么恶心。

unladen swallow: 加速Python

整了个在线将reStructuredText转成html的东西

现在不少python程序都是用reStructuredText写文档。
比较郁闷的是有部分文档都只提供了reStructuredText的源文件,没有转换好的html文件。
感觉自己每次手动转比较麻烦,于是花了点时间写了个在线的。
将reStructuredText文件贴进去,提交后就可以看到转好的页面了。

现在还有点问题,sphinx对reStructuredText进行了扩展。
对包含了sphinx标签的会处理出错(谁知道怎么忽略错误?)。
地址是 http://rest.haoluobo.com/

程序的代码可是非常的少,主要代码就是下面几行。

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
from django.http import HttpResponse
from docutils.core import publish_string

def index(request):
   html = """
<html>
       <head></head>
       <body>
       <form action="" method="post">
           <textarea name="rest" cols="60" rows="20" onfocus="this.value=”"></textarea>
           <br/>
           <input type="submit" value="提交"/>
       </form>
   </body>
</html>
   """
   if request.POST:
       html = publish_string(request.POST[‘rest’], writer_name=’html’)
   return HttpResponse(html)