Archive for the ‘python’ Category.
September 1, 2010, 5:56 pm
下面开始快速搭建Django 测试服务器(我们需要的是内建的测试服务器,而不需要apache之类的服务器软件)。从一穷二白开始,假设你用windows,步骤如下:
安装Python
上http://www.python.org官网下载2.x版本,最新版本是3.x,不过用的人太少了,2.x版本深入人心,好比xp跟win7的关系。一般是下载msi安装文件,一路next,完毕。Python会被安装在c:\Python2x目录下,最好检查一下。
设置好环境变量
下面的步骤要直接用到python命令,所以先设置好环境变量(步骤不用我说了吧),比如我的是C:\Python25。然后用cmd打开命令窗口,直接打python命令来验证是否搞成功了。
安装Django
拿出你的svn(如果没有的话就看官方教程),checkout。注意到里面有个setup.py,这是很标准的python类库安装方式(没错,django是framework也是类库),你还会看到很多python类库有类似的安装方式。直接进入django根文件夹,然后在命令后窗口下执行
python setup.py install
如果前面的步骤正确的话,这里可以直接运行了。眼看黑窗口下哗哗地,没多少时间即可完成。那么django到底安装到哪儿了呢。其实它的位置在:C:\Python25\Lib\site-packages。简单的分析一下这个路径,大概可以猜到:Lib文件夹的内容是python类库(事实就是自带的标准类库),而site-packages文件夹的内容是外部添加的类库。
设置好环境变量
又要设置一回了。这次的路径是C:\Python25\Lib\site-packages\django\bin。因为下面就要用django来建立一个服务器实例。
建立一个服务器实例
前面的工作都是准备,这回来真的。我们需要用django类库来新建一个服务器实例。这里略微解释一下“服务器实例”:要知道之前安装的django只是一套类库,不能做任何事情,而现在做的是建立一个project来做一个服务器该做的事情,当然你还能新建好多服务器实例。如何建立,用上命令行:
python django-admin.py startproject local
这里的“local”可以替换成你想要的文件夹名字,而local就是你新服务器的根目录,打开这个目录你会看到有三个文件建立起来了:
- __init__.py
- manage.py
- settings.py
- urls.py
这又是一套非常标准的python包。
验证一下
可以运行测试服务器了。在新建的服务器根目录下执行命令行:
python manage.py runserver
然后打开浏览器键入url
http://127.0.0.1:8000
非常标准的django 欢迎页面出现。
August 28, 2010, 4:52 pm
Python是一种很优雅的语言。优雅这个字,在我理解是,用最少的话表达最多的意思,说白了就是开发效率。我觉得作为程序员应该会一种优雅的语言。在紧急或者懒惰的情况下,可以最快最高效的帮助完成一些任务。作为一个flash和flex的coder,最头疼的莫过于,需要后台,至少说,需要一个测试用的后台。Python是搭建简易后台最有效率的技术之一。
这个“之一”一定要讲,不然容易造成论战。不错,除了python,有人还喜欢ruby,或者php。他们code的效率同样很高。争来争去是没有意义的,我感觉,与其耍嘴皮子,搞些有意义没意义的辩论,还不如关注你手上可以用的资源。如果你认定了Python,那么马上学习吧,拿起来就用吧,我们只是要测试用后台不是么,黑猫白猫,能抓老鼠就是好猫。邓爷爷的话一定要相信。
如果你惦记着纯用Python搭服务器,那你一定够傻了。要知道python可以做很多事情,能力很强的劣势就是,比较“底层”(当然跟C比较的话,编程效率高)。为什么不用framework呢。flash的开发效率同样比较低,所以才有flex冒出来。framework就是用来降低工作量的,就像很多所谓的牛人在给他们的产品做广告时说的那样,我们尽可能的让开发者关注业务,而不是实现。说的多好。
Django是很好很强大的web framework。它的好处是:
- 自带一个测试服务器。可以免去IIS和apache。不需要安装额外的服务器软件。
- 绝少的配置选项。
- 自带一个简易的管理系统。可以管理数据库的增删改。
- 依靠python解释执行的好处,做修改可避免服务器重启
- 快速实现MVC
上面是虚的,实的嘛,下回分解。
May 7, 2010, 7:29 pm
工作中不可避免要整Excel文档,比如统计啦排版啦。python官网中有两套类库xlwt和xlrd,不被包含在默认的python类库一起发布,而需要用setup.py install方式来安装。这两套类库的名字比较有趣,拆开来可以看成excel write read,顾名思义是用来读写Excel表格的。但是好好的为什么要两套类库呢,我猜可能是Excel的存储方式很复杂吧,于是这两套类库一个只能读,一个只能写,如果你需要读了修改后再保存,便无能为力了。如果不需要这样的话,就请继续看介绍吧。
xlrd是用来读Excel文档,下载见这里。这里一个小例子:
import xlrd
fname = "201004.xls"
main_sheet = xlrd.open_workbook(fname).sheet_by_index(0)
the_value = main_sheet.cell_value(0, 0) ##read the cell (column 0 and row 0)
xlwt是用来写Excel文档(新建并保存),下载见这里。这里有一个小例子。
import xlwt
bkw = xlwt.Workbook(encoding='utf-8')
sheet = bkw.add_sheet('sheet_name')
sheet.write(0, 0, 'the_value', xlwt.Style.default_style)
这两套类库有比较详细的doc可供查询。值得一提的是,这两套类库是如此相像,但是却不能互用。比如要修改cell的样式(如字体,加粗等),需要使用XFObject,xlwt和xlrd都有定义但却不是一样的。xlwt定义的非常广泛(见Style.py文档)。
February 20, 2009, 6:12 pm
只要定义一个write方法就行。之后随便输出到什么地方都可以。我写的就既可以写入标准输出,也可以输出到文件。用来调试程序挺有用的。版本2.5.2
class Log():
def __init__(self, filename):
self.file = open(filename, 'wt')
sys.stdout = self
def write(self,data):
self.file.write(data)
self.file.flush()
sys.__stdout__.write(data)
def __del__(self):
self.file.close()
December 9, 2008, 10:29 pm
见http://www.python.org/download/releases/3.0/
Python 3.0 (a.k.a. “Python 3000″ or “Py3k”) is a new version of the language that is incompatible with the 2.x line of releases. The language is mostly the same, but many details, especially how built-in objects like dictionaries and strings work, have changed considerably, and a lot of deprecated features have finally been removed. Also, the standard library has been reorganized in a few prominent places.
document online也变掉了,见http://docs.python.org/3.0/。
还有不可不看的what’s new in python 3.0。很多built-in的内容都变化了。
November 13, 2008, 5:30 pm
python 自带了minidom库来解析xml,用起来还算比较简单,很像一个原始版的函数库。如果看一下python manual,minidom的脉路还是很清晰的,以Node(节点)为基本要素。基本上和AS2的解析方式差不多。minidom包含如下几种Node类别:
- Node
- NodeList
- DocumentType
- Document
- Element
- Attr
- Comment
- Text
- ProcessingInstructure
貌似几乎涵盖了所有xml元素。其中Node是所有XML元素的基类。里面最最常用的就是Document,Element和Text了。
- Document代表了xml文档,由一个很常用的属性叫documentElement,就是根节点,是一个Element对象。一般用parse解析xml文件,或者用parseString转换xml样式的字符串,来得到Document
- Element代表一般节点,常用属性有tagName(节点名称)等。通常都是用遍历方式来获得子节点的。minidom有个比较恼人的地方就是它不能忽略注释和空白,所以在遍历的时候要注意查看nodeType(Node类的属性,节点类型,Element是1,Text是3),然后再去看tagName。
- Text是文本节点。比如有一段xml:<p>paragraph</p>。它是一个Element,那么Element的子节点就是Text节点,如果要获得字符串就用data属性。按这个例子,获得字符串paragraph的方法是:Element.firstChild.data
minidom解析xml还算比较方便。俺也是刚入门。以后学多了继续写啊。
October 17, 2008, 10:08 am
看了这么多书,第一次发现这么快就能转化为实际生产力的。
昨天晚上狠狠的郁闷了一把。开发python程序的时候不管我怎么修改py文件,就是不出想要的成果(我是用ant来build的)。我发现每次运行print的内容都一样,好像我根本没改过。我查看了一下pyc的创建日期,发现它根本没更新过。难道ant不好使了。
猛然由一个念头提醒了我。因为这个py文件是从国外的同事那里拿过来的,由于时差py的创建时间是低于pyc的。而python解释器是这样运行的:如果发现py的时间大于pyc,则认为py被更新了编译py到pyc,如果不是就直接用import pyc。由此便造成了这个编译问题。
October 13, 2008, 2:44 pm
看python源码剖析有一种云开雾散的感觉。今天忍不住谈谈让自己印象很深的LEGB作用域规则。python的名字空间,作用域规则是一种静态规则,变量查找是决定于code文本位置,而不是动态决定的。LEGB分别代表Local,Enclosing,Global和Built-in域,这是查找变量具体内容的先后顺序,即先从local域找,然后是嵌套的最内一层域,global域,builtin函数库。理论有点难懂,还是看看例子吧。
>>> a=2
>>> def pp():
print a
a = 3
print a
>>> pp()
Traceback (most recent call last):
File "<pyshell#6>", line 1, in <module>
pp()
File "<pyshell#5>", line 2, in pp
print a
UnboundLocalError: local variable 'a' referenced before assignment
>>> def calls():
a = 3
def pps():
print a
return pps
>>> ppc = calls()
>>> ppc()
3
>>>
例子分为两部分。先看看函数pp,运行结果报异常,它的意思是本地变量a在赋值前就被引用了,如果在c或c++里应该是2才对(动态决定的),但是按照静态的LEGB规则,就该这么解释:由于后面有语句a=3,说明变量名a属于local域(这里还牵涉到一个概念是变量名在域内任何地方可见),注意变量名字在python中非常重要,查找全凭名字,所以在第一个print a行里,python认为变量名字a是属于local域的,但是还没有被定义。
例子后半部分,使用了嵌套函数。ppc()最后运行的结果说明,a最后对应的是calls内a,而不是global的a。那还是因为LEGB规则,print a在local域内找不到a,接下来就会查找“E”域,即最内嵌套的域。
September 28, 2008, 1:16 am
开始研究pyamf的用处了。
pyamf(http://www.pyamf.org)是一个很好的amf中间件,能跟django, twisted, google app engine等流行框架整合。现在我要做的就是pyamf结合django 1.0。据说flex通过amf做PRC调用似乎节省掉很多带宽。
下载
去官网找到svn地址,checkout下来之后install,很简单。python真是一种很简洁很强大的语言,和flex很配啊。
处理机制
既然跟django结合,就应该有一套处理request,response的机制。pyamf里对应的就是pyamf.remoting.gateway.django模块。打开能看到有一个类class DjangoGateway(gateway.BaseGateway),它就是整个处理流程的主干。class document很好的解释了它在django中的用法。仅仅需要在views.py中建立一个DjangoGateway实例,这个实例是urlmap对应的处理函数,它把从django底层传递过来的request(其实是AMF编码过的)解码,并映射相应的python对象,然后执行注册的RPC方法(就是flex调用amf过程中看到的方法调用)返回一个response,最后用AMF机制编码这个response,返回给django。这样django再通过层层处理返回这个AMF信息给flex。如此便是一个完整的amf PRC调用过程。很多的server基本上都是基于类似的机制,通过中间件层层过滤request和response,达到隔离底层处理的目的。最后我们能看到,django内部处理amf的调用是如此之简单。
DjangoGateway有两个方法很重要,一个是__call__(python的特殊名字方法,自己定义的方法不能用这些名字哦,__call__使得对象能像方法那样用,比如有对象a,执行a()相当于执行a.__call__()。也许可以猜到了,没错,在django里urlmap需要有一个对应的处理函数,__call__就是起这个处理函数的作用)。还有一个就是getResponse方法。它的作用是处理解码后的request,这是一些很普通的方法调用,因为request已经AMF解码了,它会寻找合适的PRC方法(选择的依据就是AMF指定的方法名,也就是flex调用amf url时的方法名)来处理request。我把这两个方法贴上来了。里面重点扯了一下__call__加深印象。
def getResponse(self, http_request, request):
"""
Processes the AMF request, returning an AMF response.
@param http_request: The underlying HTTP Request.
@type http_request: C{HTTPRequest}
@param request: The AMF Request.
@type request: L{Envelope
}
@rtype: L{Envelope
}
@return: The AMF Response.
"""
response = remoting.Envelope(request.amfVersion, request.clientType)
for name, message in request:
processor = self.getProcessor(message)
response[name] = processor(message, http_request=http_request)
return response
def __call__(self, http_request):
"""
Processes and dispatches the request. 解码request,并处理
@param http_request: The C{HTTPRequest} object. 来自django底层的httprequest对象,body还是被AMF编码的
@type http_request: C{HTTPRequest}
@return: The response to the request. 返回一个AMF编码过的response对象
@rtype: C{HTTPResponse}
"""
if http_request.method != 'POST':
return http.HttpResponseNotAllowed(['POST'])
context = pyamf.get_context(pyamf.AMF0)
stream = None
http_response = http.HttpResponse()
# Decode the request 解码request对象
try:
request = remoting.decode(http_request.raw_post_data, context)
except pyamf.DecodeError:
self.logger.exception(gateway.format_exception())
http_response.status_code = 400
return http_response
self.logger.debug("AMF Request: %r" % request)
# Process the request 处理request,这里它调用了getResponse,就会按照指定的方法名来正式处理request
try:
response = self.getResponse(http_request, request)
except (KeyboardInterrupt, SystemExit):
raise
except:
self.logger.exception(gateway.format_exception())
return http.HttpResponseServerError()
self.logger.debug("AMF Response: %r" % response)
# Encode the response 编码response,在返回之前要用AMF编码好
try:
stream = remoting.encode(response, context)
except pyamf.EncodeError:
self.logger.exception(gateway.format_exception())
return http.HttpResponseServerError('Unable to encode the response')
buf = stream.getvalue()
http_response['Content-Type'] = remoting.CONTENT_TYPE
http_response['Content-Length'] = str(len(buf))
http_response['Server'] = gateway.SERVER_NAME
http_response.write(buf)
return http_response
September 19, 2008, 6:19 pm
昨天晚上坐火车回家,顺便带上了这边刚买的书在路上看看,书已经被我压在枕头下两天,再不看真不是我的风格。说实话我对C了解的还比较基础,上大学的时候直接就学了C++,后来再没看过(不是计算机科班出身的基础是要差不少)。我只看了第一章,还看得很慢,不过感觉真的非常好,原来“一切都是对象”的理念是可以这么构建出来的。真是一本很刺激的书。(我无意做广告啊)。当时我就在想,AS差不多也是这个理念吧,不知道它是怎么实现的,可惜还没开源。python把每样东西都看成对象,相应的为没个对象开辟一块内存区域,比如类,称之为“类型对象”。比如
这样一声明,一个叫A的类型对象就在内存中开辟出来了,它的父类是object类型对象。类型对象的类型是一个特殊的对象,貌似无法直接用到。:-),看得还比较浅,不扯了。