关于‘Python’

笔记:Ubuntu下快速开始使用Python Thrift

发表于2012年2月8日

本文介绍如何在Ubuntu 10.04下安装Apache Thrift并用Python写一个Demo。

apt-get install libboost-dev libevent-dev python-dev automake pkg-config libtool flex bison sun-java6-jdk
wget http://www.apache.org/dist//thrift/0.8.0/thrift-0.8.0.tar.gz
tar zxvf thrift-0.8.0.tar.gz
cd thrift-0.8.0
./configure
make
sudo make install
sudo pip install thrift

编辑接口文件 hellowworld.thrift:

service HelloWorld {
    string ping(),
    string say(1:string msg)
}

编辑 server.py

#!/usr/bin/env python
 
import socket
import sys
sys.path.append('./gen-py')
 
from helloworld import HelloWorld
from helloworld.ttypes import *
 
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
from thrift.server import TServer
 
class HelloWorldHandler:
  def ping(self):
    return "pong"
 
  def say(self, msg):
    ret = "Received: " + msg
    print ret
    return ret
 
handler = HelloWorldHandler()
processor = HelloWorld.Processor(handler)
transport = TSocket.TServerSocket("localhost", 9090)
tfactory = TTransport.TBufferedTransportFactory()
pfactory = TBinaryProtocol.TBinaryProtocolFactory()
 
server = TServer.TSimpleServer(processor, transport, tfactory, pfactory)
 
print "Starting thrift server in python..."
server.serve()
print "done!"

编辑 client.py

#!/usr/bin/env python
 
import sys
sys.path.append('./gen-py')
 
from helloworld import HelloWorld
 
from thrift import Thrift
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
 
try:
  transport = TSocket.TSocket('localhost', 9090)
  transport = TTransport.TBufferedTransport(transport)
  protocol = TBinaryProtocol.TBinaryProtocol(transport)
  client = HelloWorld.Client(protocol)
  transport.open()
 
  print "client - ping"
  print "server - " + client.ping()
 
  print "client - say"
  msg = client.say("Hello!")
  print "server - " + msg
 
  transport.close()
 
except Thrift.TException, ex:
  print "%s" % (ex.message)
thrift --gen py helloworld.thrift
python server.py
python client.py

参考: Thrift the missing guide

Python处理Last-Modified

发表于2011年11月16日

Python检查某个URI是否有修改,可以检查HTTP Response的Last-Modified字段

import urllib2
import datetime
from urllib2 import HTTPError
import datetime
def check_modified(url, last_modified, field_name="Last-Modified"):
    request = urllib2.Request(url) 
    opener = urllib2.build_opener() 
    request.add_header('If-Modified-Since', last_modified)
    try:
        resp = opener.open(request)
        print "Last-Modified: " + resp.headers.get(field_name)
    except HTTPError as e:
        if 304 == e.code:
            print "Not Modified Since: " + last_modified
 
last_modified = datetime.datetime(2011,11,15,0,0).strftime("%a, %d %h %Y %H:%M:%S GMT")
check_modified('http://www.kuaishubao.com', last_modified)

有的服务器并不返回Last-Modified, 所以需要看情况处理,比如

check_modified('http://sunliwen.com', last_modified, field_name="date")

参考:http://www.faqs.org/rfcs/rfc2616.html

用Python Decorator简化代码

发表于2011年10月14日

看码不说话。

def deco(callable):
    def method(a, b):
        print "a: %s" % a
        print "b: %s" % b
        return callable(a, b)
    return method
 
@deco
def test1(a,b):
    print a+b
 
test1(10,20)

上面的Decorator只能装饰有两个参数的函数,否则

@deco
def test2(a,b,c):
    print a+b+c

会报错

>>> test2(10,20,30)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: method() takes exactly 2 arguments (3 given)

如需支持装饰任意参数的函数,得使用以下方法:

def deco(callable):
    def method(*args, **kws):
        print "args: %s" % repr(args)
        print "kws: %s" % repr(kws)
        return callable(*args, **kws)
    return method
 
@deco
def test1(a,b):
    print a+b
 
@deco
def test2(a,b,c):
    print a+b+c
 
test1(10,20)
test1(10,b=20)
test2(10,20,30)
test2(10,b=20,c=30)

结果是:

>>> test1(10,20)
args: (10, 20)
args: {}
30
>>> test1(10,b=20)
args: (10,)
args: {'b': 20}
30
>>> test2(10,20,30)
args: (10, 20, 30)
args: {}
60
>>> test2(10,b=20,c=30)
args: (10,)
args: {'c': 30, 'b': 20}
60