2008/04/13

Python: classmethod & staticmethod 区别

没有评论:

classmethod:类方法
staticmethod:静态方法

在python中,静态方法和类方法都是可以通过类对象和类对象实例访问。但是区别是:

  • @classmethod 是一个函数修饰符,它表示接下来的是一个类方法,而对于平常我们见到的则叫做实例方法。 类方法的第一个参数cls,而实例方法的第一个参数是self,表示该类的一个实例。
  • 普通对象方法至少需要一个self参数,代表类对象实例
  • 类方法有类变量cls传入,从而可以用cls做一些相关的处理。并且有子类继承时,调用该类方法时,传入的类变量cls是子类,而非父类对于类方法,可以通过类来调用,就像C.f(),有点类似C++中的静态方法, 也可以通过类的一个实例来调用,就像C().f(),这里C(),写成这样之后它就是类的一个实例了。
  • 静态方法则没有,它基本上跟一个全局函数相同,一般来说用的很少
Example 1:

>>> class a():

@staticmethod
def staticm():
print 'static'
def normalm(self):
print 'nomarl',self
@classmethod
def classm(cls):
print 'class',cls


>>> a1=a()
>>> a1.normalm()
nomarl <__main__.a instance at 0x84dddec>
>>> a1.staticm()
static
>>> a1.classm()
class __main__.a
>>> type(a)
<type 'classobj'>
>>> type(a1)
<type 'instance'>



Example 2:

class A(object):
@classmethod
def cm(cls):
print '类方法cm(cls)调用者:', cls.__name__
@staticmethod
def sm():
print '静态方法sm()被调用'

class B(A):
pass

A.cm()
B.cm()

A.sm()
B.sm()

输出:

类方法cm(cls)调用者: A
类方法cm(cls)调用者: B
静态方法sm()被调用
静态方法sm()被调用

2008/04/09

Python 下的图形界面开发

没有评论:

据我所知有三种:
1。 用 glade产生图形界面, 即 python + gtk + glade. 此法生成的界面最美观.
import pygtk, gtk, gtk.glade
一个只用 gtk, 没用glade工具的例子
import pygtk
import gtk

class HelloWorld:
def hello(self,widget,data=None):
print "Hello World!"

def delete_event(self,widget,data=None):
print "delete_event"
return gtk.FALSE

def destroy(self,widget,data=None):
gtk.main_quit()

def __init__(self):
self.window=gtk.Window(gtk.WINDOW_TOPLEVEL)
self.window.connect("delete_event",self.delete_event)
self.window.connect("destroy",self.destroy)
self.window.set_border_width(10)
self.button=gtk.Button("Hello World!") self.button.connect("clicked",self.hello,None)
self.button.connect_object("clicked",gtk.Widget.destroy,self.window)
self.window.add(self.button)

self.button.show()
self.window.show()

def main(self):
gtk.main()

if __ name__=="__main__":
hello=HelloWorld()
hello.main()

2。 用 Tkinter 即 gui based on Tcl/tk .此绘图法最为简单,可能需要安装 python-tk.参考 python_notes.pdf -> Tkinter programming
example:
import Tkinter
#创建一个窗体:
wnd = Tk()
#加一个按钮:
btn = Button(master=wnd, text="Exit",command=wnd.quit)
btn.pack() #pack之后才显示

#或者通常把 btn 加到 wnd 下面:
wnd.btn = Button(master=wnd, text="Exit", command=wnd.quit)
wnd.btn.pack()

#最后, 让这个窗口跑起来:
wnd.mainloop()

3. 用 wxPython。一个例子是手机上的图形界面。参考python for S60 doc.pdf -> wxpthon 模块部分,或 www.wxpython.org .
import appuifw
import e32

def bexit():
app_lock.signal()

def addtext() :
t = appuifw.query(u'Input text:', 'text')
r.add(unicode(t))

r = appuifw.Text()
r.set(u'info:\n')
appuifw.app.screen = 'normal'
appuifw.app.menu = [(u'Add', addtext), (u'Exit', bexit)]
appuifw.app.body = r
appuifw.app.exit_key_handler = bexit
app_lock = e32.Ao_lock()
app_lock.wait()


python tkinter: 一个画圆的例子

from Tkinter import *

canvas = Canvas(width=300, height=300, bg='white')
canvas.pack(expand=YES, fill=BOTH)

canvas.create_oval(10, 10, 200, 200, width=2, fill='blue')

mainloop()


Python线程编程的两种方式

没有评论:

一种是函数式
一种是用类来包装的线程对象。

1、调用thread模块中的start_new_thread()函数来产生新的线程,请看代码:
### thread_example.py
import time
import thread
def timer(no,interval): #自己写的线程函数
while True:
print 'Thread :(%d) Time:%s'%(no,time.ctime())
time.sleep(interval)
def test():
thread.start_new_thread(timer,(1,1)) #使用thread.start_new_thread()来产生2个新的线程
thread.start_new_thread(timer,(2,3))
if __name__=='__main__':
test()

这个是thread.start_new_thread(function,args[,kwargs]) 函数原型,其中function参数是你将要调用的线程函数;args是讲传递给你的线程函数的参数,他必须是个tuple类型;而kwargs是可选的参数。
线程的结束一般依靠线程函数的自然结束;也可以在线程函数中调用thread.exit(),他抛出SystemExit exception,达到退出线程的目的。

2、通过调用threading模块继承threading.Thread类来包装一个线程对象。请看代码
### threading_example.py
import threading
import time
class timer(threading.Thread): #我的timer类继承自threading.Thread类
def __init__(self,no,interval):
threading.Thread.__init__(self) #在我重写__init__方法的时候要记得调用基类的__init__方法
self.no=no
self.interval=interval
def run(self): #重写run()方法,把自己的线程函数的代码放到这里
while True:
print 'Thread Object (%d), Time:%s'%(self.no,time.ctime())
time.sleep(self.interval)
def test():
threadone=timer(1,1) #产生2个线程对象
threadtwo=timer(2,3)
threadone.start()#通过调用线程对象的.start()方法来激活线程
threadtwo.start()
if __name__=='__main__':
test()

2008/04/08

Django开发及mod_python安装

没有评论:

python+Django+apache+mysql 开发网站,different from LAMP which mainly uses PHP

也许大伙都听说过 Ruby on Rails? 一个以 ruby 写的 RAD framework; django 与它大约同期诞生, 两者有着相近的目标, 各自的哲学. (有意思的是: RoR 和 django 的作者之前都是 php 开发方面的高手!)

django 现在官方站点上发布的版本是 0.91, 但是这不过这只是对外的一个静态的小版本, 而其 svn 中每天都有更新, 如果要学习 django 的话, 还是建议从它的 svn 中直接取出最新的版本. 尤其是 magic-removal 分支 - 这将会成为 django 下一个版本: 0.92.

magic-removal 是 django 开发人员们目前正在全力耕作的一个分支 (branch), 最大的目标就是将 django 多年遗留下来的一些疙疙瘩瘩的地方做一次 "大扫除", 以期提升 django 这一开发框架的简洁性与易用性.

如何安装
http://www.djangoproject.com/documentation/install/
简单说,下载version 0.96,解压,然后执行
sudo python setup.py install
如果用于开发,最好之前安装mod_python, which embeds Python within Apache and loads Python code into memory when the server starts. Code stays in memory throughout the life of an Apache process, which leads to significant performance gains over other server arrangements. Make sure you have Apache installed, with the mod_python module activated. Django requires Apache 2.x and mod_python 3.x.

但是据说mod_python和 mod_php冲突,所以现在还在犹豫是否安装Django。本机上原来装有bbPress based on LAMP(php).

Django 中文文档
http://www.yarshure.com/documentation/

Django step by step 中文
http://www.woodpecker.org.cn/obp/django/django-stepbystep/newtest/doc/


Ubuntu下mod_python的安装

目的: 为了能在网页中嵌入python代码
环境: Ubuntu, apache2, python2.5, 并且已安装 apache2-php5 (安装完后php依旧工作,哈哈)

步骤:
首先安装 mod_python .
sudo apt-get install libapache2-mod-python, 或用synaptic装亦可

(按mod_python的说明步骤要安装apxs,但是apache2找不到apxs,因为这种方式已过时了。apache将所有的载入的包都放在
/etc/apache2/mods-enabled 即可加载! 注: apache2的 ServerRoot = /etc/apache2 )

然后检查是否已在 mods-enabled目录下, 如有,则不用执行下面命令:
cd /etc/apache2/mods-enabled/
sudo ln -s ../mods-available/mod_python.load mod_python.load

接着,编辑:
cd /etc/apache2/sites-available/
sudo gedit default

On line 10 you should have:

Options Indexes FollowSymLinks MultiViews
AllowOverride AuthConfig
Order allow,deny
allow from all
# Uncomment this directive is you want to see apache2's
# default start page (in /apache2-default) when you go to /
#RedirectMatch ^/$ /apache2-default/

加入新行后变为:

Options Indexes FollowSymLinks MultiViews
AllowOverride AuthConfig
Order allow,deny
allow from all

AddHandler mod_python .py
PythonHandler mod_python.publisher
PythonDebug On

# Uncomment this directive is you want to see apache2's
# default start page (in /apache2-default) when you go to /
#RedirectMatch ^/$ /apache2-default/

(注: 该文件被链接到 /etc/apache2/sites-enabled/000-default 。)

现在重启 apache server:
sudo /etc/init.d/apache2 restart

测试:
sudo gedit /var/www/test.py
文件内容如下:
def index(req):
return "Test successful";

访问 http://localhost/test.py 应该可以看到 "Test successful" in plain text。


一个显示网页的python程序

import sys
import time

def index(req):

# Following line causes error to be sent to browser
# rather than to log file (great for debug!)

sys.stderr = sys.stdout

#print "Content-type: text/html\n"

#print """
blah1 = """<html>
<head><title>A page from Python</title></head>
<body>
<h4>This page is generated by a Python script!</h4>
The current date and time is """

now = time.gmtime()
displaytime = time.strftime("%A %d %B %Y, %X",now)

#print displaytime,
blah1 += displaytime

#print """
blah1 += """
<hr>
Well House Consultants demonstration
</body>
</html>
"""
return blah1

重载Python类对象的打印函数

没有评论:
class G:
def __init__(self):
g.nodes = "all nodes of G"
def __repr__(self):
return self.nodes
...
g = G()
print G

Python中的全局变量

没有评论:

全局变量

这里谈全局变量呢,倒不是说Python和c的全局变量概念不同,他们的概念是相同的。只是在使用机制上,是有一些差异的。举个例子:

– module.py –
globalvar = 1

def func():
print globalvar
# This makes someglobal readonly,
# any attempt to write to someglobal
# would create a new local variable.

def func2():
global globalvar
globalvar = 2
# this allows you to manipulate the global
# variable

在 func这个函数中,globalvar是只读的。如果你使用了globalvar = xxx这种赋值语句,Python会重新创造一个新的本地对象并将新值赋给它,原来的对象值不变。而在func2函数中,由于我们事先申明了 globalvar是global的,那么此时的更改就直接在全局变量上生效。

很明显这和c中的使用机制是不一样的,在c中,我们只要在函数外的全局区域申明了变量,就可以在函数中直接对其操作,不用还申明一个global。

Python中的时间操作

没有评论:

Python中的时间操作还是比较方便的,有专门的time模块提供多种接口形式。其中常用的两种操作数据格 式就是滴答和时间元组,关于这两个奇怪的名字,我也不便解释,总之在一本书上看着这么写,也就这么用,确实很难听。滴答是从1970年开始到现在的秒数, 在Python2.4.3中是一个浮点数,小数部分为更精密的部分,小于1秒的精细时间值。时间元组是一个具有9个成员的元组,依次为:年、月、日、小 时、分钟、秒、星期(0-6,0为周一)、一年中的哪一天(1-366,古罗马历)、Daylight savings(-1,0,1,我也不知是干什么用的)。

所以可以用如下方法提取当天的当时时间:

a,a,a,hour,minute,second,a,a,a=time.localtime(time.time())

这里的hour、minute、second分别是当时的时、分、秒,也是比较常用的参数。另外就是关于求时间差,如果使用 time.localtime()测定时间差,那么滴答值为0时的中国标准时间是1970年1月1日8:00,时间差无从谈起,所以对于时间差应该使用 time.gmtime()转换为TimeTuple再解包为各个时间参量。比如如下获得时间差:

a,a,a,hour,minute,second,a,a,a=time.gmtime(t1-t2)


对 dictionary of datetime排序

通常用 listObj.sort()排序,如果需要定义自己的排序方式,则:
1. 定义一个排序函数
def dictionary_datetime_sorter( d1, d2):
if d1 elif d1>d2: return 1
else: return 0

...
2. 将此函数作为sort()的input 对 list 排序。调用格式:
datetimeList.sort(dictionary_datetime_sorter)


2008/04/05

在source insight中添加 python language

没有评论:

语言包从该处下载:
http://www.sourceinsight.com/public/languages/

To import a custom language file into Source Insight:

1. Select Options > Preferences. Click the Languages tab.

2. Click the Import button. Select and load the custom language file (.CLF)

3. You should now see the new language in the list of languages.

4. Click the Document Types button to open the Document Options dialog box.

5. If you don't have a document type already created for the type of language file, you will need to create one now. If you already have a document type created, select it in the list and go to step 7.

6. Click the Add Type button to create a new document type. Give it a name that describes the type of file. For example, "Ant File". Click OK and then fill in the file filter text box with a wildcard. For example, "*.ant".

7. In the Parsing section of the Document Options dialog box, select the newly imported language in the language drop-down list. This is what associates your document type with the custom language.

8. Click the Close button to close Document Options. Then click OK to close the Preferences dialog box.

2008/04/04

Python的时间操作 2

没有评论:
字符串是使用静态的方式进行存储,只能读而不能直接修改字符内容。特别将一堆对字符串并在一起的时候,虽然可以直接相加,听说这样的速度奇慢,只有用其它函数的方式进行,好在也不太麻烦。

比如用 print ','.join(datelist)

就可以将datelist列表里面的所有项目并成一个字符串,当然这个表达式会在每一个项目中间插入一个逗号,这种方式比用循环的方式更简洁。

日期的操作必须使用time或datetime库

import time
>>> s="2006-1-2"
>>> time.strptime(s,"%Y-%m-%d)
这是将字符串格式的日期及时间转成日期对象
转义符对应意义如下
%a 本地简化星期名称
%A 本地完整星期名称
%b 本地简化的月份名称
%B 本地完整的月份名称
%c 本地相应的日期表示和时间表示
%d 月内中的一天(0-31)
%H 24小时制小时数(0-23)
%I 12小时制小时数(01-12)
%j 年内的一天(001-366)
%m 月份(01-12)
%M 分钟数(00=59)
%p 本地A.M.或P.M.的等价符
%S 秒(00-59)
%U 一年中的星期数(00-53)星期天为星期的开始
%w 星期(0-6),星期天为星期的开始
%W 一年中的星期数(00-53)星期一为星期的开始
%x 本地相应的日期表示
%X 本地相应的时间表示
%y 两位数的年份表示(00-99)
%Y 四位数的年份表示(000-9999)
%Z 当前时区的名称
%% %号本身

============================================

#-*- coding:utf-8 -*-

import time
import datetime

# 2007-11-25 15:36:35

#使用datetime模块可以很方便的解决这个问题,举例如下:

d1 = datetime.datetime(2005, 2, 16)
d2 = datetime.datetime(2004, 12, 31)

# 结果:47
print (d1 - d2).days

#上例演示了计算两个日期相差天数的计算。

starttime = datetime.datetime.now()

endtime = datetime.datetime.now()
print (endtime - starttime).seconds

#上例演示了计算运行时间的例子,以秒进行显示。

d1 = datetime.datetime.now()
d3 = d1 + datetime.timedelta(days =10)

print str(d3)
print d3.ctime()

# 上例演示了计算当前时间向后10天的时间。
# 如果是小时 days 换成 hours

# 其本上常用的类有:datetime和timedelta两个。它们之间可以相互加减。
# 每个类都有一些方法和属性可以查看具体的值,如datetime可以查看:天数(day),小时数(hour),星期几(weekday())等;
# timedelta可以查看:天数(days),秒数(seconds) 等。

#
# time , datetime , string 类型互相转换
#
# string -> time
# time.strptime(publishDate,"%Y-%m-%d %H:%M:%S")
#
# time -> string
# time.strftime("%y-%m-%d",t)

date = '2007-01-01'

print type(date)

date = time.strptime(date,"%Y-%m-%d")

print type(date)

print date[0]

d4 = datetime.datetime(date[0], date[1],date[2])

print d4
print type(d4)

#将日期时间对象转成字符串则要用

date = time.strftime("%y-%m-%d",date)
print type(date)

#其中d为日期时间对象