阿当的博客











{七月 17, 2010}   [ python ] input()和raw_input()
input() 传进来的参数是表达式,会运行的,raw_input()的参数只是字符串。

===============================
def test():
~a = 1
~b = 2
~c = input("input your number:")
~d = raw_input("input your number:")

test()
# 先后输入两次 a + b
# => 3
# => a + b
===============================

使用raw_input()会更安全。



{七月 16, 2010}   python中对文件、文件夹的操作
python中对文件、文件夹的操作需要涉及到os模块和shutil模块。

创建文件:
1) os.mknod("test.txt")       创建空文件
2) open("test.txt",w)           直接打开一个文件,如果文件不存在则创建文件

创建目录:
os.mkdir("file")                   创建目录

复制文件:
shutil.copyfile("oldfile","newfile")       oldfile和newfile都只能是文件
shutil.copy("oldfile","newfile")            oldfile只能是文件夹,newfile可以是文件,也可以是目标目录

复制文件夹:
shutil.copytree("olddir","newdir")        olddir和newdir都只能是目录,且newdir必须不存在

重命名文件(目录)
os.rename("oldname","newname")       文件或目录都是使用这条命令

移动文件(目录)
shutil.move("oldpos","newpos")   

删除文件
os.remove("file")

删除目录
os.rmdir("dir")                   只能删除空目录
shutil.rmtree("dir")            空目录、有内容的目录都可以删 

转换目录
os.chdir("path")                  换路径

判断目标
os.path.exists("goal")          判断目标是否存在
os.path.isdir("goal")             判断目标是否目录
os.path.isfile("goal")            判断目标是否文件                 



{七月 15, 2010}   [ js ] 可否用多线程的思路,解决大数量数据的性能问题?
    js中也是有线程概念的,setTimeout,setInterval和ajax都是这样的例子,另起一个线程,时间上似乎是并行处理的。于是,我想是不是可以利用这个多线程的机制,优化一下大数量数据遍历时的性能问题呢?

写了个demo如下:
====================================================
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>阿当制作</title>
</head>

<body>
<div id="box1"></div>
<div id="box2"></div>
<div id="box3"></div>
<div id="box4"></div>
<div id="box5"></div>
<div id="box6"></div>
<div id="box7"></div>
<div id="box8"></div>
<p>方法1耗时:<span id="time1"></span>微秒</p>
<p>方法2耗时:<span id="time2"></span>微秒</p>
<script type="text/javascript">
var box1 = document.getElementById("box1");
var box2 = document.getElementById("box2");
var box3 = document.getElementById("box3");
var box4 = document.getElementById("box4");
var box5 = document.getElementById("box5");
var box6 = document.getElementById("box6");
var box7 = document.getElementById("box7");
var box8 = document.getElementById("box8");
var time1 = document.getElementById("time1");
var time2 = document.getElementById("time2");

function addItems(box,str,color,callback){
function addItem(){
var node = document.createElement("span");   
node.innerHTML = str;
node.style.color = color;
box.appendChild(node);
}
for(var i=0;i<9999;i++){
addItem();
}
if(callback) callback();
}

function testFun(){
var t = new Date().getTime();
addItems(box1,"1","blue");
addItems(box2,"2","green");
addItems(box3,"3","red");
addItems(box4,"4","yellow");
var t2 = new Date().getTime();
time1.innerHTML = t2 – t;
}

function testFun2(){
var t2,n = 0,t = new Date().getTime();
setTimeout(function(){addItems(box5,"1","blue",callback);},0);
setTimeout(function(){addItems(box6,"2","green",callback);},0);
setTimeout(function(){addItems(box7,"3","red",callback);},0);
setTimeout(function(){addItems(box8,"4","yellow",callback);},0);

function callback(){
n++;
if(n==4){
t2 = new Date().getTime();
time2.innerHTML = t2 – t;
}
}
}

testFun();
testFun2();
</script>
</body>
</html>
====================================================

思路很简单,我有8个div容器,想给每个容器里填入9999个span元素。4个一组,想看看一个线程串行处理的速度快,还是分4个线程并行处理的速度快。

结果很意外:
=====================
在firefox下

在chrome下

在opera下

在ie8下

除了在opera这个怪胎下多线程的方式快了一点儿,别的浏览器下都是单线程更快。(可是,opera怎么把我的输出输了三遍啊?这何解啊?+_+)

我猜js所谓的“多线程”,其实还是单线程,只是cpu把任务时间分成了一小段一小段,然后分别去处理这多个线程,同一时间只有一个线程可以被处理。如果线程越多,反而越让cpu频于在多个任务间切换,反而影响了速度。



{七月 15, 2010}   python学习笔记(七)
1) enumerate函数。 字典可以通过for .. in obj.items()进行遍历,索引和值都能取到,但对于列表,for .. in就只能取到值,取不到索引了。enumerate()函数就是为了解决这个问题而出现的。
================================
a = {"name":"adang","sex":"male"}
b = ["a","b","c"]

for x,y in a.items() :
》print x,":",y

for x in b :
》print x

for x,y in enumerate(b) :
》print x,":",y
================================

2) 在python中序列是可以进行乘法运算的,表示重复不地多少次,包括字符串、列表和元组都可以用乘法。
================================
"123" * 3       #=> "123123123"
[1,2,3] * 3     #=> [1,2,3,1,2,3,1,2,3]
(1,2,3) * 3     #=> (1,2,3,1,2,3,1,2,3)
================================

3) 模块的属性。 dir(mod)可以返回mod的所有方法和属性,包括公有的和私有的。mod.__all__可以返回mod的公有接口。用mod.__all__会相对更准确地知道模块哪些方法可以安全地使用。mod.__file__可以返回mod的路径,方便我们去查看它的源代码。注意,在模块中以__all__ = ["a","b","c"]声明模块的公有接口是非常好的习惯。



{七月 15, 2010}   python学习笔记(六)
1) os模块。 os模块的path.split()方法可以将路径拆分成“路径部分”和“文件部分”,而path.splitext()方法可以将路径拆分成“非扩展名部分”和“扩展名部分”。path.abspath()方法可以将相对路径转换成绝对路径。因为在window下路径是用\分隔的,而在linux下,路径用/分隔,为了兼容不同系统,所以常常用os.path.join()方法来连接路径,os.path.join()会自动识别当前系统,选用合适的分隔符,从而做到跨系统兼容。
======================================
import os
a = "/etc/abc.txt"
os.path.split(a)           #=> ("/etc","abc.txt")
os.path.splitext(a)      #=> ("/etc/abc",".txt")
======================================

2) urllib模块。 和ruby一样,open只能读本地文件,如果要抓取网页,需要导入模块。
======================================
import urllib
str = urllib.urlopen("http://www.baidu.com").read()
print str
======================================

3) ConfigParser模块。 ConfigParser模块是用来处理配置文件的。将配置项专门放到一个配置文件里是个好习惯,用ConfigParser模块可以很方便地对配置文件进行修改。相应的,配置文件也要遵循一个标准格式。ConfigParser有read()方法,用于读取配置文件,sections()方法,用于获取所有小节,options(section)用于获取指定小节的所有配置项,get(section,option)获取指定配置项的值,set(section,option,value)用于设置指定配置项的值。
======================================
配置文件 abc :

[portal]
url = http://%(host)s:%(port)s/Portal
username = adang
host = localhost
password = 1234
port = 80

主文件:
from ConfigParser import ConfigParser
config = ConfigParser()
config.read("abc")
url = config.get("portal","url")
print url                    #=> http://localhost:80/Portal
======================================

4)time模块。 和时间相关的操作。

import time
time.time()           取得时间戳
time.ctime()         可读性稍好一些的字符串
time.localtime()    返回当前时间域的当前时间,可读性一般
time.localtime().tm_mday    返回月分
time.localtime().tm_wday    返回星期
time.localtime().tm_yday     返回年份

6) ElementTree模块。 处理XML的模块。

import xml.etree.ElementTree

7) random模块。 随机模块。

import random
random.randint(n,m)                         生成n~m之间的随机整数
random.randrange(n,m,l)                  生成n~m-1之间的随机数,数字之间的间隔为l
如random.randrange(20,201,2)        生成20~200之间的偶数
random.random()                              不能传参,生成0~1之间的浮点数
random.uniform(n,m)                         生成n~m之间的浮点数
random.shuffle(arr)                            给列表重新洗牌。对列表是破坏性的操作。
如arr = [1,2,3] ; random.shuffle(arr)  

8) webbrowser模块。 此模块可以处理浏览器相关的事情。

import webbrowser
webbrowser.open(‘http://www.yahoo.com’)        #=> 打开浏览器,跳到www.yahoo.com页面

9) shelve模块。 此模块有点像js控制cookie一样,它可以负责将数据持久化,不同的是,它是保存在一个文件而不是cookie中。此文件直接打开不具可读性,只能用模块自己来保存和查看。shelve自己处理了数据的序列化和反序列化,可以把它保存的数据理解为一个字典对象。

import shelve
s = shelve.open("mybase")
s["name"] = "adang"
s["sex"] = "male"
print s       {‘name’:'adang’,’sex’:'male’}



{七月 15, 2010}   python小游戏——猜数字2.0
  前天完成了首个python小游戏,今天给它升级了下,加入了排名功能。用的次数少,排名在前十的,可以排到排行榜中。没有用数据库,太小,还用不上,写到了个文本文件中。

====================================================
gameMain.py 文件:

#_*_ coding: utf-8 _*_
from gameStart import gameStart
from scoreList import *
def showMenu() :
print ”’
[ 猜数字游戏菜单 ]
==================================

<1> 开始游戏
<2> 高分排行榜
<3> 退出游戏
”’   

def selectAct() :
yourAct = raw_input(">> 请输入您想要执行的操作,并按回车键确认 :")
if yourAct == "1" :
gameStart()   
elif yourAct == "2" :
showScoreList()   
elif yourAct == "3" :
print ">> 游戏结束,谢谢您的参与。\n==================================="
else :
print ">> 没有指定的选项。"
selectAct()

def init():
showMenu()
selectAct()

init()

gameStart.py:

#_*_ coding: utf-8 _*_
import random,scoreList
def gameStart() :
>>print ”’
[猜数字游戏开始]
==================================
”’
goalNum = random.randint(0,99)
tip = ">> 请您猜一个数字,此数字介于0~99之间:"
guessCount = 0
while True :
while True:
try:
yourNum = raw_input(tip)
yourNum = int(yourNum)
break
except:
print ">> 您输入的不是数字。"
tip = ">> 请您再猜:"
guessCount += 1
if yourNum < goalNum :
print ">> (您猜的数小了 T_T)"
elif yourNum > goalNum :
print ">> (您猜的数大了 T_T)"
else :
print ">> (恭喜您猜中了 ^0^ , 您共猜了 %s 次猜中了结果)" % guessCount
break

scoreList.updateScoreList(guessCount)
while True:
continueFlag = raw_input(">> 游戏结束。您还想再玩一次吗? y | n : ")
if continueFlag == "y" :
gameStart()
break
elif continueFlag == "n" :
print ">> 游戏结束,谢谢您的参与。\n==================================="
break
else :
print ">> 请您输入y或n"

scoreList.py:

#_*_ coding:utf-8 _*_
import os
scoreListFile = "scoreList.txt"
def showScoreList() :
print ”’
[ 高分排行榜 ]
=================================

排名     姓名     次数
------------”’
if not os.path.exists(scoreListFile) :
for i in range(1,11) :
print "<%s>     暂缺     x" % formatNum(i)
else :
f = open(scoreListFile)
try :
lines = f.readlines();
for i in lines :
print i
finally :
f.close()

def updateScoreList(count) :
if os.path.exists(scoreListFile) :
f = open(scoreListFile,"r")
try :
lines = f.readlines()
i = 0;
for x in lines :
i += 1
if count < int(x.split()[2]) :
name = raw_input(">> 恭喜您进入前十的排名,请输入您的尊姓大名(不超过三个字): ")
name = name[:3]
string = "<%s>     %s     %s\n" % (formatNum(i),name,count)
lines[i-1] = string
f.close()
f = open(scoreListFile,"w")
f.writelines(lines)
f.flush()
break
else :
pass
finally :
f.close()       
else :
name = raw_input(">> 恭喜您进入前十的排名,请输入您的尊姓大名(不超过三个字): ")
name = name[:3]
string = "<%s>     %s     %s" % (formatNum(1),name,count)
for i in range(2,11) :
string += "\n<%s>     暂缺     9999" % formatNum(i)
f = open(scoreListFile,"w")
f.write(string)
f.flush()
f.close()

def formatNum(n) :
n = int(n)
if n < 10 :
return "0" + str(n)
else :
return n
====================================================

一点心得:
1) python中对文件的读写操作是分开的,要么是读要么是写,不能又读又写,如果想写先读后写,需要先open(file),然后在close(),再然后open(file,"w"),要关闭以前是不能进行写操作的。

2)  用write()方法写,有的时候还要注意调flush()方法将缓冲区的内容写到磁盘上,不然有可能会产生问题。



{七月 14, 2010}   python学习笔记(五)
1) python的数组操作功能比js强大,比起ruby会少很多方法,但已非常够用了。老实说,功能过多,也让人头晕,恰好够用可能更好。
========================================
test = [1,2,3]
test.append(4)         #=> [1,2,3,4]             相当于push
test.extend([5,6])     #=> [1,2,3,4,5,6]       合并两个数组
test += [7,8]             #=> [1,2,3,4,5,6,7,8] 合并两个数组,和extend效果相似。+号不会改变test的值,而是生成一个新值,而extend会改变test的值。也就是说,extend是破坏性的方法
test.remove(3)         #=> [1,2,4,5,6]          删除第一个3
del test[3]                 #=> [1,2,4,6]             删除位置下标为3的元素
test.insert(2,3)          #=> [1,2,3,4,6]         在下标为2的位置,添加元素3
test.reverse()            #=> [6,4,3,2,1]         逆向
test.pop()                  #=> [6,4,3,2]            向最后一个数弹出去
test.pop(2)                #=> [6,4,2]               向下标为2的元素弹出去
test.index(4)              #=> 1                       返回第一个值为4的元素的下标
test.sort()                  #=> [2,4,6]               排序
test.count(4)             #=> 1                       返回数组中4出现的次数
len(test)                    #=> 3                       返回数组的长度
========================================

几个值得注意的地方:
《1》 数组可以直接相加,结果为把两个数组直接拼接起来;
《2》 数组删除元素可以用arr.remove()方法,也可以用del arr[i]方法,两者分别是通过值和通过位置进行删除;
《3》 可以使用count()方法统计元素出现的次数;
《4》 pop()方法可以传参,弹出指定下标的元素。

2) python中列表没有map方法,但有种奇怪的用法类似于map,被称为列表推导式。
========================================
arr = [1,2,3]
[3*x for x in arr if x>1]               #=> [6,9]
[(x,2*x) for x in arr]                   #=> [(1,2),(2,4),(3,6)]     
========================================

3) 如果不会引起误解的话,元组可以省略()号。如果元组只有一个数值,也一定要在结尾处加“,”,这是为了防止和()引起误解。
========================================
t = 123,456,"hello"               # 效果等同于 t = (123,456,"hello")
t = 123,                                # 效果等同于 t = (123,)
========================================

4) python中类似于ruby也可以做集合的操作,不同的是,ruby的集合操作是对数组进行运算,而python中集合是专门一种类型。
========================================
s = set(['a','b','c'])
len(s)               #=> 3
‘a’ in s              #=> True
‘d’ not in s        #=> True       not的用法可真语义啊  效果同 not "d" in s ,但语义更强,赞一个
t = set(['a','b','c','d'])
s <= t               #=> True        s是否t的子集
s >= t               #=> False       s是否t的超集
s | t                  #=> set(['a','b','c','d'])      s 和 t的合集
s & t                 #=> set(['a','b','c'])          s 和 t的交集
s – t                  #=> set([])        s和t的集合的差
t – s                  #=> set(['d'])     t和s的集合的差
========================================

5) dict对象。 dict对象有clear()方法,用于清除自己的所有内容,变成一个空的{}。dict也有传址的问题,数组的传址问题是利用[:]来解决的,dict的传址问题可以用copy()方法,但如果dict的元素本身也是复杂类型,copy就解决不了了,这时就需要利copy模块的deepcopy()方法了。
=========================================

>>> d = {‘age’: 42, ‘name’: ‘Gumby’}

>>> d

{‘age’: 42, ‘name’: ‘Gumby’}

>>> d.clear()

>>> d

{}
=========================================

>>> x = {‘username’: ‘admin’, ‘machines’: ['foo', 'bar', 'baz']}

>>> y = x.copy()

>>> y['username'] = ‘mlh’

>>> y['machines'].remove(‘bar’)

>>> y

{‘username’: ‘mlh’, ‘machines’: ['foo', 'baz']}

>>> x

{‘username’: ‘admin’, ‘machines’: ['foo', 'baz']}
=========================================

>>> from copy import deepcopy

>>> d = {}

>>> d['names'] = ['Alfred', 'Bertrand']

>>> c = d.copy()

>>> dc = deepcopy(d)

>>> d['names'].append(‘Clive’)

>>> c

{‘names’: ['Alfred', 'Bertrand', 'Clive']}

>>> dc

{‘names’: ['Alfred', 'Bertrand']}
=========================================

6) dict对象有items()方法和iteritems()方法,它们的返回值是有区别的,items()返回的是列表对象,而iteritems返回的是iterator对象。同理还有keys()方法和values()方法。

7) id()方法。 python中每个对象都有一个id,指向的是它的内存地址,这个和ruby的__id__原理一样。

8) python中所有类的基类也是object。汗,这种设计思路怎么这么流行啊。



{七月 13, 2010}   python中的in运算符
in在python中也是计算,是python中所有序列都支持的一种基础的的方便的运算。
====================================
a = ‘12345′
print ‘1′ in a         #=> True

a = (1,2,3,4)
print 1 in a           #=> True

a = [1,2,3,4]
print 1 in a           #=> True

a = {1:11, 2:22, 3:33}
print 1 in a           #=> True               (只能是索引,不能是内容,比如11 in a就会是False)

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



{七月 13, 2010}   首个python程序,一个猜数字的小游戏 ^0^
python上手还真的是不难,呵。写了个猜数字的小游戏。

==================================================
#_*_ coding: utf-8 _*_
import random
print ”’
===================================
[猜数字游戏开始]”’
def guessNum() :
~goalNum = random.randint(0,99)
~tip = "\n请您猜一个数字,此数字介于0~99之间:"
~guessCount = 0
~while True :
~~yourNum = raw_input(tip)
~~yourNum = int(yourNum)
~~tip = "请您再猜:"
~~guessCount += 1
~~if yourNum < goalNum :
~~~print ">> (您猜的数小了 T_T)"
~~elif yourNum > goalNum :
~~~print ">> (您猜的数大了 T_T)"
~~else :
~~~print ">> (恭喜您猜中了 ^0^ , 您共猜了 %s 次猜中了结果)" % guessCount
~~~break
~continueFlag = raw_input("游戏结束。您还想再玩一次吗? y | n : ")
~if continueFlag == "y" :
~~guessNum()
~elif continueFlag == "n" :
~~print "游戏结束,谢谢您的参与。\n==================================="
~else :
~~print "请您输入y或n"

guessNum()
==================================================
截图:



{七月 13, 2010}   python生成随机数
import random
random.randint(0,99)




about

打造高品质的前端代码

pages
categories
archive
et cetera