2007/04/26

python学习笔记(五): 正则表达式

>>> s = '100 BROAD'
>>> re.sub('ROAD$', 'RD.', s) #匹配以ROAD字串结尾的内容,替换成RD., $表示是以这个字串结尾的.
'100 BRD.'
>>> re.sub('\\bROAD$', 'RD.', s) #\b表有边界,比如前面有一个空格或断行等,但之前还有一个\,这里将不会转义.
'100 BROAD'
>>> re.sub(r'\bROAD$', 'RD.', s)
'100 BROAD'
>>> s = '100 BROAD ROAD APT. 3'
>>> re.sub(r'\bROAD$', 'RD.', s)
'100 BROAD ROAD APT. 3'
>>> re.sub(r'\bROAD\b', 'RD.', s)
'100 BROAD RD. APT 3'

加了r代表使用原始字符串,但这里的"原始字符串"有些难理解,既然字符串的内容不转义,为什么\b被解释成一个边界符?

r'^m?m$', 这里意思,必须以m开始,以及m结束的某个字符串,且中间以?代替,说明只允许出现一个字符串.
略过了一些内容.

正则还是有一些模糊,感觉这个更来得直观一些:正则表达式之道(A Tao of Regular Expressions)

2007/04/24

python学习笔记(四) 文件对象

读文件: f=open("/test.txt","r")
第一个参考为要打开的文件名,第二个为文件打开方式
r为只读,不能做其他操作.
w为写模式,会把原文件overwrite
a为追加模式,会在原文件的末属加入要写入的内容
rb,以二字进方式只读打开
f.name 得到文件名
f.mode 得到当前文件的打开方式
f.tell() 得到当前对象正操作文件的哪个位置
f.seek(length, start)移动文件中的操作位置,接收两参数,打开多少,从哪里打开
f.read() 可接收一个参数,返回指定长度内容,如查不写,则返回全部内容
f.closed 当前文件对象是否已关闭,返回False, or True



这里f被自动创建了一个文件对象,拥有文件对象的一些其他功能
f.read() 是读此文件,会打印出此文件的全部内容
print f

try:
f=open("test.txt","r")# 如果此文件不存在的话,会引发错误
except IOError:#这里的错误类型是可选的,这相当于多加了一个条件判断,如果不是IOError则不会执行此代码块的内容
f.close()
else:
...
这里还可以加一个判断,如果不是IOError错误,则执行else:下的代码块.

>>> import fileinfo
>>> print '\n'.join(sys.modules.keys())

在这里可以看到fileinfo已经被作为sys的一个modele存在了
这里比较含糊

一直对split的工作方式有些奇怪,不知道用什么特征来分割字符串的.

os.listdir(dirname)
返回给定目录下的所有内容,包括文件和目录,相当于DOS下的DIR?

列出所有文件:需要做个判断,isfile
>>> [f for f in os.listdir(dirname)
... if os.path.isfile(os.path.join(dirname, f))]

列出所有目录
>>> [f for f in os.listdir(dirname)
... if os.path.isdir(os.path.join(dirname, f))]

>>> import glob
>>> glob.glob('c:\\music\\_singles\\*.mp3')
找出当前目录下的所有MP3文件,这个好用


----
睡觉去.

2007/04/19

python学习笔记(三) : 面向对象

在python任何事物都是对象,这样理解非常方便.

from mod import method
此书的作者说不推荐使用这种方式,不爽,因为Django中到处都在使用这种方式.不过import mod.method的形式也很方便,这似乎同JAVA中的导入很像.

slef原来不是关键字,只是约定俗成的一个命名,这相当于JAVA中的this关键词.

__init__ 方法是可选的,但是一旦你定义了,就必须记得显示调用父类的 __init__ 方法(如果它定义了的话)。
这一点比较重,如果父类定义了__init__, 子类如果继续,必须显示调用此方法.
like this:
---
class a(A):
def __init__(self):
A.__init__(self)

python是自动进行内存管理的,就是说你创建对象的任何实例时无须显式销毁,python会做这个工作,会自动进行垃圾回收.当对象没有被观察时,它们就消失了.

"应该总是在 __init__ 方法中给一个实例的所有数据属性赋予一个初始值。"
我以前总是喜欢直接这样:
class a:
a1=""
b1=""
而不是写在__init__中
"在 Python 中,只有类属性可以定义在这里,数据属性定义在 __init__ 方法中。"这里不太理解.什么是数据属性?什么是类属性?

"is" and "=="

is 比较判断两个物理地址, ==比较两个值.

私有函数
class a:
def __private(slef):
两个下划线

2007/04/18

python学习笔记(二)

python的内省

type 返回任意对象的类型
str 将对象转换为字符类型
>>>str(None)
>>>'None'

dir(test) # 返回任意对象的属性或方法,结果是字符型的

getattr 获取对象引用
getattr(object,method) # 等同于object.method
getattr(object,method,object.method_default)# 如果object.method不能访问则自动将第三个参数的值返回: object.method_default

列表的过滤
[elem for elem in li if len(elem) > 1]
elem与for结合, if对for负责
elem在li中,且字串长度>1

[elem for elem in li if elem != "b"]
[elem for elem in li if li.count(elem) == 1]

and 与 or的字符运算有些晦涩 :(

lambda 是个怪胎,慎用!
我情愿定义一个def 寒!语义和结构都不清晰,一些怪胎们为了精简代码,居然发明了这种变态的写法,寒,也许是我的刻意拒绝.:(

split
如果不带参数,将用空格来划分

if a is None:...
if a==None:..
哪个更快?第一个.

ljust(n) 用空格填写到指定长度
>>>s='aaaa'
>>>s.lust(5)
>>>'aaa '

2007/04/17

python学习笔记(一)

之前粗粗地看了一遍《dive in python》,我觉着要温习一下,打牢些基础。

这个刚上手的字符串操作有些难度哦。

join是加入的意思,默写一个例子:

def test(testStr):
return ";"join(["%s=%s" % k,v for k,v in (testStr.items())])

a={
"a1":1,
"a2":2,
"a2":2,
}
test(a)
>>>a1=1;a2=2;a3=3

把后面数组里的每一个对象用;分隔开。

python是动态强类型语言。类型可以动态获取,但类型之间的转换是严格的。

def a():
""" 这是一个测试函数"""
# ...
访问函数的说明文档:a.__doc__
这个东西的好处在于一些函数的说明可以放在里面,不看源代码的时候也可以访问说明内容。中!
-----------
import
from myapp import blog
这个时候我可以使用blog对象的任何方法OR属性
blog.add
blog.edit
blog.del


sys.path, append

系统路径,就是模块路径,有系统路径,还可以手动增加,系统路径(sys.path)是一个内置的列表(list),所以可以使用append来增加一个对象,增加需要使用的路径
sys.path.append("/myapp/")

万物皆对象
有了这个定义外,就不要老烦着想什么是面象的思想方法等难稿的概念.


代码缩进
这个约定使代码看起来非常优美,结构非常清晰,然后,我在想有一天,python的创始人可能会放弃这一约定.

几个有用的属性

模块如果正被自己运行,而不是被其他程序导入被当做引入模块执行时,可以使用默认属性__name__来判断:

if __name__ == "__main__":
print "您好像正在自己运行着,没有被别人导入 :) "

字典
我不知道把a={}这里的a称作为数组还是字典,不过Dictionary直译的话就是字典的意思,我总是与PHP的数组分不开.
a={"a1"="1","a2"=2}
>>>a["a1"]
>>>"1"
似乎不支持a[0]这样的访问,文章说支持key的类型混用,就是说a[0]被当作键名为0的对象,而不是第一个
添加: 加一个不存在的键名即是添加
删除: del a["a1"]
删除全部: a.clear()
--------

数组
晕,真正的数组是list, :(
list['1','2','3','4']
list[0] 值 '1'
list[-2] 倒数第二个,倒数的时候应在数组项目很多的时候使用比较方便
数组切片
list[1:3] 第2个开始取,取3个,因为数组从0开始计数,这里会有误解,会为从第二取到第四 -_-
list[:3] 首开始位置不写默认为0,即第1个
list[2:] 末尾不写,则表示当前数组长度,从第3个取到最后
list[:] 从开始取到最后,取所有
第一个值为开始位置,第二个值为取的长度

list.append("new") 追回一个元素
list.insert(2,"new2") 插入一个元素,位置在2
list.extend(['tt','cc']) 连接两个数组,把第二个里面的元素添加到第二个里面,现在第一个里面多了两个
list.append(['ss','dd']) 此时会把后面的元素当做一个对象追回到list的末尾,是当做一个对象处理,而不是当作两上元素
list.index("new") 搜索"new"在list中的首次出现的位置
list.remove("new") 删除"new"这个元素
list.pop() 删除list的最后一个元素,并返回被删除的这个元素的值
list+list2, list+['google'],list+=['baidu'],list=list*3 数组的相加,会把list2中的值加到list的末尾,也可以用乘法,会复制3份,如 1,2,3,1,2,3,1,2,3

tuple
tuple(序列)是固长的数组,不能改变长度,并且没有任何方法,是不是一些如果原始不变的数据就可以放在这里,比如网站的一些固定标题或配置文件一类的东西

批量赋值
(a,b,c)=3
v=(1,2,3)
(a,b,c)=v
a=1,b=2,c=3
可以将序列内的值分别赋给a,b,c

range(7)
是一个数组,界定范围为7个,从0到6,是不是range函数定义的值都是为数字?

"$s=%s" % (a,b)
哦,原来这是一个序列(固长的数组)操作方式,以前只是记者这个固定形式

a=6
print "this is: " + a
会报错,因为a是整型int, 而前面是字符串str, 类型不一样,不能这样链接,哦,晕,似乎不方便哦?
得改成 print "this is %s" % a ...汗!

>>> print "Today's stock price: %f" % 50.4625
50.462500 # 浮点数,默认为6位
>>> print "Today's stock price: %.2f" % 50.4625
50.46 # 浮点数,保留2位小数
>>> print "Change since yesterday: %+.2f" % 1.5
+1.50 # 浮点数,输出值的符号并保留两位小数

>>>li = [1,2,3,4]
>>>[elem*2 for elem in li]
会输出什么?
[2,4,6,8]

items是字典类型数据的一个函数
test.imtes() 会返回一个tuple类型的list,不可变长的数据,把前面的字典变成了固长的序开

>>>li = ['server=mpilgrim', 'uid=sa', 'database=master', 'pwd=secret']
>>>s=";"join(li)
呵,这下写出来顺多了,这里就像第一节的例子一样
返回值是什么呢?
>>>'server=mpilgrim;uid=sa;database=master;pwd=secret'
以;为分隔符一个字符串
怎么重新分隔开来?
s.split(";",1) 会分隔开来,但这里有一个1限制,只是分隔一次,就是只处理了第一个;,后面的没有处理


还没学完,这位作者留了一招,狠! 如何把所有的;处理掉?可以不写或者要写上固定长度么?
s.split(";",len(s))
?
s.split(";")
?

困了,最近工作不顺,条理都没有了,又对网络有些无趣的感觉.

睡觉去! 我还在网吧呢 -_-

2007/04/15

Django的URL是如何写的?

urls.py
----
from django.conf.urls.defaults import *
urlpatterns = patterns('qcx.blog.views',
(r'^now/$', current_datetime),#以“now/”开头,后面不要任何字符时
(r'^now/plus(\d{1,2})hours/$', hours_ahead),#“plus”为常量字符,(\d{1,2}) 数字1-2位
(r'^now/minus(\d{1,2})hours/$', hours_behind),
(r'^now/in_chicago/$', now_in_chicago),
(r'^now/in_london/$', now_in_london),
)

Django开发版本有了一些小变化

http://www.djangoproject.com/weblog/2007/apr/06/changes/
Examples of some of these changes are:
Removing the auto_now and auto_now_add options in Django models.
Finishing and merging the "newforms-admin" branch, which changes the way admin options are specified (and gives you a lot more flexibility).
Removing the LazyDate shortcut.
Renaming django.contrib.localflavor.usa to django.contrib.localflavor.us.
The biggest change is probably the newforms-admin functionality.

Django开发版本有了一些小变化
auto_now(不论何种条件若更新则更新为当前时间值), auto_now_add(仅在产生新记录时添加当前时间值) 这是DateTimeField的两个对象,被移除了,不过认为auto_now_add还有一些保留的必要,这样在具体写代码时,就可以不考虑时间值这个东西,感觉还是蛮好的东西

LazyDate 不记得为何物了
newforms-admin 最怕自动化的东西

Django是如何工作的?

一个工作目录下至少可能有这些东西
/urls.py
/sets.py
...

/qcx/ #project
/qcx/blog/ # app 比如一个投票/BLOG/相册等

models.py 用来写数据表结构
views.py 用来写程序代码

modes.py
----
...
class entry(models.model):
  #...

views.py
---
from django.http import HttpResponse
from qcx.blog.models import entry

def AddSave():
  #...

def EditSave():
  #...

def EditForm():
  #...

def EntryList():
  #...

在sets.py中设置数据库相关信息
在urls.py中做URL设置

manage.py runserver

访问相关目录,如果程序没错的话,就可以正常访问了

Django安装测试

http://www.djangoproject.com
下载安装文件

python setup.py install
把django-admin.py所在目录放到系统环境变量中,这个主要是为了在开发中使用django-admin的一些功能

现在就可以工作了

进入工作目录(你自己把测试代码放哪,就进入哪儿):
cd d:\web\python\django
manage.py startproject qcx # 建立此次的工作目录,被称为project,可以理解为一个站点,以后所有的应用将在这个project下建app,application
cd qcx
manage.py startapp blog # 现在可以建一个app玩一下了
---
blog目录下有三个文件:
__init__.py
view.py
models.py
这两个是主要的东西,models.py用来写数据表的结构,view.py用来写程序代码

hello, Django!

from django.http import HttpResponse
class test:
def hello():
return HttpResponse("hello, Django!")

djangoTest=test()
djangoTest.hello()

hello, python!

def hellopython():
return "hello, python!"