Posts tagged ‘Python’

PyAMF的Subversion 地址更换

在更新PyAMF的时候发现总是出现bug:

svn: Target path does not exist

到pyamf.org上去发现首页改版了,Subverion的地址也改了,新地址是:

svn co http://svn.pyamf.org/trunk pyamf

用PEP 8检查Python Coding风格

今天才知道有个检查Python程序风格的工具:pep8。PEP8来源于Python官方的《Python Developers Guide》的第8章节:Style Guide for Python Code,主要讲述Python编码的统一风格,网上能搜到很多中文翻译版本。写了一段时间的Python程序,还真的没有仔细看过Python Developers Guide,平常一直都是翻阅《Learning Python》,要找个时间看看这个文档了。

PEP8的程序托管在github上,下载安装后可以运行pep8这个命令,参数就是要检查的Python文件,不符合PEP8规范的地方都会在输出信息里面列出来:

optparse.py:69:11: E401 multiple imports on one line
optparse.py:77:1: E302 expected 2 blank lines, found 1
optparse.py:88:5: E301 expected 1 blank line, found 0
optparse.py:222:34: W602 deprecated form of raising exception
optparse.py:347:31: E211 whitespace before '('
optparse.py:357:17: E201 whitespace after '{'
optparse.py:472:29: E221 multiple spaces before operator
optparse.py:544:21: W601 .has_key() is deprecated, use 'in'

最好使用–show-pep8参数,它会在每个不符合规范的地方都加入解释。

python-twitter 验证 Twitter用户名密码

Twitter 的 API 提供一个验证用户的接口,如果验证用户名密码成功,返回用户的Profile信息。python-twitter也提供了封装,下面是个使用的例子,

import simplejson
import twitter
 
USERNAME = 'xxxxxx'
PASSWORD = 'xxxxxx'
 
try:
    api = twitter.Api(username = USERNAME, password = PASSWORD)
    user = api.VerifyCredentials()
    print 'Verify Credentials Success: %s' % user.name
except:
    print 'Verify Credentials Error'

Python 使用 GData-Client-Python 库访问Youtube数据

使用Python和gdata-python-client就可以访问Google的诸多服务,下面的例子是访问Youtube.com视频的方法。在Youtube.com的API站点找到的:

import gdata.youtube
import gdata.youtube.service
 
yt_service = gdata.youtube.service.YouTubeService()
entry = yt_service.GetYouTubeVideoEntry(video_id='TGbwL8kSpEk')
 
def PrintEntryDetails(entry):
    print 'Video title: %s' % entry.media.title.text
    print 'Video published on: %s ' % entry.published.text
    print 'Video description: %s' % entry.media.description.text
    print 'Video category: %s' % entry.media.category[0].text
    print 'Video tags: %s' % entry.media.keywords.text
    print 'Video watch page: %s' % entry.media.player.url
    print 'Video flash player URL: %s' % entry.GetSwfUrl()
    print 'Video duration: %s' % entry.media.duration.seconds
 
    # show alternate formats
    for alternate_format in entry.media.content:
        if 'isDefault' not in alternate_format.extension_attributes:
            print 'Alternate format: %s | url: %s ' % (alternate_format.type, alternate_format.url)
 
    # show thumbnails
    for thumbnail in entry.media.thumbnail:
        urls = thumbnail.url.split('/')
        ids = urls[len(urls) - 1].split('.')
        print ids[0]
        print 'Thumbnail url: %s' % thumbnail.url
 
PrintEntryDetails(entry)

[App Engine] Google App Engine 10个应用的限制

Google App Engine默认是容许用户最多创建10个应用,如果你已经用完了10个怎么办?

Chinese 方式:申请更多的Google Account,为每个账户申请GAE。
American 方式:到邮件列表发个Email,说明自己的情况,请Google Support来处理。

今天在邮件列表里面见到一封这样的信,Google的Support人员在2天后为他增加了10个应用的限制。

[Django] settings.py 中设置访问 MySQL 数据库

Django访问数据库的设置是在settings.py中写入数据库的engine、用户名和密码,默认的写法是:

DATABASE_ENGINE = 'mysql' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. 
DATABASE_NAME = 'xxx' # Or path to database file if using sqlite3. 
DATABASE_USER = 'root' # Not used with sqlite3. 
DATABASE_PASSWORD = 'xxx' # Not used with sqlite3. 
DATABASE_HOST = 'localhost' # Set to empty string for localhost. Not used with sqlite3. 
DATABASE_PORT = '3306' # Set to empty string for default. Not used with sqlite3.

数据库的关键信息都写在settings.py中,这样做是非常不安全的。现在可以在settings.py里面使用DATABASE项代替以上的配置项,username和password可以写在配置文件中。下面是把username和password放到MySQL数据库的配置文件中,由DATABASE项读取的示例:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'OPTIONS': {
            'read_default_file': '/etc/mysql/my.cnf',
        },
    }
}
# my.cnf
[client]
database = xxx
user = xxx
password = xxxxxx
default-character-set = utf8

也可以在DATABASES中加入NAME来指定数据库名,client中去除database选项,HOST和PORT这些也都可以写在my.cnf文件中。

[Google AppEngine] 中使用Flex实现Google Account SignIn/SignOut

在AppEngine中可以使用Google Account实现认证。如果使用Flex Application作为UI,使用按钮实现Sign In/Sign Out需要把URL通过HTML页面的FlashVars传递到Flex Application中。但是这个URL的值是几个HTTP地址经过&符号拼接而成,在Flex里通过FlexGlobals.topLevelApplication.parameters读取的时候只能读取第一个&符号前的地址。所以这个URL需要在Python代码里面进行URL encode,在Flex Application中URL decode。

Python代码:

    def get (self):
        user = users.get_current_user()
        #Check login user
        if user:
            sign = urllib2.quote(users.create_logout_url('/openparty'))
        else:
            sign = urllib2.quote(users.create_login_url('/openparty'))
        #Init template vars
        template_values = {
            'sign' : sign,
        }

Flex代码:

  var url : String = decodeURI(FlexGlobals.topLevelApplication.parameters['sign']);

[Google AppEngine] app.yaml的skip_files

app.yaml的skip_files项通过设置正则表达式,设置在Upload过程中不被上传到AppEngine的文件和文件夹。 这个skip_files有默认值:

skip_files: |
 ^(.*/)?(
 (app\.yaml)|
 (app\.yml)|
 (index\.yaml)|
 (index\.yml)|
 (#.*#)|
 (.*~)|
 (.*\.py[co])|
 (.*/RCS/.*)|
 (\..*)|
 )$

如果需要修改默认值,需要在app.yaml中重写skip_files的值。下面的例子加入了.bak和.DS_Store在排除的文件中:

skip_files:
- ^(.*/)?app\.yaml
- ^(.*/)?app\.yml
- ^(.*/)?index\.yaml
- ^(.*/)?index\.yml
- ^(.*/)?#.*#
- ^(.*/)?.*~
- ^(.*/)?.*\.py[co]
- ^(.*/)?.*/RCS/.*
- ^(.*/)?\..*
- ^(.*/)?.*\.bak$
- ^(.*/)?.DS_Store

这个写法跟AppEngine刚刚发布的时候不一样,不清楚是在哪个版本更新中进行了修改。AppEngine的新版本不断的发布,不知道最后的版本会带来什么功能。

介绍一个名为Picky的AppEngine项目,是@livid开发的基于AppEngine的博客应用。源代码在:http://code.google.com/p/project-picky

File Iterator

《Learning Python》中介绍了Iterator Protocol,很多Built-in对象都实现了它。对于语言内部的实现或者其他类型使用Iterator的效率没有测试,只是简单的测试了File Iterator。先是准备了一个330M的文件,然后用推荐的写法和传统的readlines写法读入文件的内容。

传统的写法:

def read_files_readlines():
    print str(datetime.datetime.now())
    data = ''
    f = open('test.data', 'r')
    for line in f.readlines():
        data += line
    print str(datetime.datetime.now())

推荐的写法:

def read_files_iterators():
    data = ''
    print str(datetime.datetime.now())
    for line in open('test.data'):
        data += line
    print str(datetime.datetime.now())

测试的结果使用Iterator在速度上的优势并不明显,只是比readlines函数快了几秒;但是在内存方面Iterator全面胜出,内存最高使用了200M,readlines的方法占用了1000M左右。推荐在Python的代码中使用Iterator的写法,尤其是在web方面的应用。

MySQL-Python在Snow Leopard上安装编译

如果不使用port替换系统的Python,那么所有Python的Library都要自己下载安装。当安装MySQL-Python的时候,会说找不到mysql_config。需要到目录下修改setup_posix.py的26行,指定系统的MySQL配置文件的地址,再执行安装的命令就没有问题了。这里我用port安装的mysql5:

mysql_config.path = "/opt/local/bin/mysql_config5"