1、Python是解释型语言。
2、在python解释器下,下划线"_"存储了上次计算的结果。
3、关于print的写法:print("Hi!")是Python2和3的,print "Hi!"是Python2的。
4、程序退出的方法:*nix(Ctrl+D)、Windows(Ctrl+Z)、程序中(raise SystemExit异常)
5、每一行算一条语句,如果要一行中表示多条,用分号";"分割。
6、Block靠缩进识别(一般为4个空格),没有花括号。
7、如果Block下暂时没有代码,(如分支的某个if)必须用pass代替,否则格式会报错。
8、类似printf的print方法:print( "%3d %.2f" % (year,) ),即用百分号“%”分割。
9、python没有switch,只能用if和elif:
if suffix == ".htm": content = "text/html" elif suffix == ".jpg": content = "image/jpeg" elif suffix == ".png: centent = "image/png" else: raise RUntimeError("Unknown content type")
10、in是操作符号,用在sequence(map、list、tuple等)中时,检查seq中是否含有某元素。用在字符串中时,检查是否为子串,返回True或者False。
#检查元素 arr = [1,2,3,4,5] if 1 in arr: print "Has 1" else: print "None" #查找字串 if "spam" in s: has_spam = True else: has_spam = False
11、文件读写
基础版本代码,性能较低,因为将会把所有数据都读入内存!后面几章会介绍使用yield的版本,不会都调入内存,性能更好。
代码1:比较初级
f = open("../ExpInfoDAO.cc") line = f.readline() while line: print line, #这里加上,会防止多换一行。 line = f.readline() f.close()
代码2:更简洁,只有两行!
for line in open("../ExpInfoDAO.cc"): print line,
如果想要输出到文件怎么办呢?
假设已经打开f = open("out","w")
print >>f,"Hi" #Python2的方法
print("Hi",file=f) #Python3的方法
12、字符串string:包含在单、双、三引号中:'Hi',"Hi"。三引号可多行,多用于doc:
“”“
I
can
do
it
"""
13、string也是sequence的一种,但是是不可变的!(immutable,和tuple一样)
14、字符串可用加号+连接:g = a + "Test string"。
可以slice(切分、取字串):
a = "Hello world."
b = a[4] # a == "o"
b = a[:5] # a=="Hello"
类似的,用2~3个下标可非常轻松的取出字串
15、string->其他:使用int()、float()将字符串强制转化为其他类型:
>>> x = int("12") >>> x 12
16、其他->string:使用str()、repr()、format()。str一般是直接字符转换(直译)、repr是翻译为内置类型的字符串(译意),format翻译完了再格式化。
>>> x = 3L >>> str(x) '3' >>> repc(x) >>> repr(x) '3L' >>> format(x,"0.5f") '3.00000'
17、list是sequence的一种,用方括号表示:[1,2,"3",4,[5,6]]。可以嵌套任意类型。
18、list的基础操作:slice、加运算、list复合(comprehension)
#slice >>> names = ["Li","He","Yuan"] >>> names[:1] ['Li'] #加运算 >>> names_2 = ["Liu"] >>> names + names_2 ['Li', 'He', 'Yuan', 'Liu']
复合运算是比较高级的一种,如下,以打开文件、打印每行为例:
lines = [line for line in open("../test.txt")] for line in lines: print line,
上面这个例子这么用有些繁琐,但是做数值计算时候非常有用,经常很有用,比如,求幻方:
>>> [x*x for x in xrange(1,10)] [1, 4, 9, 16, 25, 36, 49, 64, 81]
19、Tuples,它和list同属sequence,用圆括号表示,区别是它是不可变的!相对比list更省内存。
20、Tuples的用途很广泛
函数return返回多个值:
#arr = [1,2,3,4,5] def minmax(arr): m1 = min(arr) m2 = max(arr) return (m1,m2) #结果: >>> minmax(arr) (1, 5)
再比如for时候的unpack解包:
m = [(1,"liheyuan"),(2,"liuxinrui")] for (name,id) in m: print name," ",id,
21、set,类似stl和java里的set,非重复无序元素集合,必须用set()函数创建。
#3不会重复的! >>> set([1,2,3,3,4,5]) set([1, 2, 3, 4, 5])
通过add()或者update()都用来添加!前者更新单个元素,后者可写入sequence。
s = set("1","2","3")
s.add("x")
s.update([1,2,3,4])
、
通过remove()来删除
s.remove("x")
22、Dictionaries(叫法奇怪啊,我更愿意叫map),用花括号写。
stock = { "name": "GOOG", "shares": 100, "price": 490.10 }
要说明的是:任何不可变类型都可做key
23、Dictionaries的操作:访问value、更新、删除、转化为list。
可以直接用下标来完成。
#访问value,直接下标 >>> stock["shares"] 100 #更新value,也用下标! >>> stock["shares"] = 200 >>> print stock {'price': 490.10000000000002, 'name': 'GOOG', 'shares': 200} #删除一个key(和value) >>> del stock["shares"] >>> print stock {'price': 490.10000000000002, 'name': 'GOOG'} #转化为list(只转化key) >>> list(stock) ['price', 'name']
24、for循环和迭代。
#range一次产生 >>> range(10) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] #xrange是迭代的产生 >>> xrange(10) xrange(10) #迭代上面的stock >>> for key in stock: ... print key,stock[key] ... price 490.1 name GOOG
说明:在Python3中,xrange已经被合并为了range。
25、函数定义:
def remainder(a,b): q = a//b r = a - q * b return (q,r) if __name__ == "__main__": print remainder(30,7) #结果: (4, 2)
26、Generators(生成器、发射器),是一个很有用的功能,可以理解为函数级的”管道“。
def countdown(n): print "Ready for countdown..." for i xrange(n): yield i #用法:获取函数的handle后,依次调用next()来获取下一通过”管道“发射过来的数值。 >>> c = countdown(10) >>> c.next() Ready for countdown... 0 >>> c.next() 1 >>> c.close()
27、用yield(发射器)来模拟*nix的常用命令:“tail -f log|grep key“
import os,time def tail(f): f.seek(0,os.SEEK_END) while True: line = f.readline() if not line: time.sleep(0.1) continue else: yield line def grep(lines,key): for line in lines: #注意:必须有是for,不能省略! if key in line: yield line if __name__ == "__main__": for line in grep(tail(open("log")),"python"): print line,
28、Coroutines(协同程序)
协同程序与发射器有区别,但类似:
line = (yied) #用括号( )把yield围起来了。
与发射器相反,程序中的协同语句将阻塞,直到send()塞入消息为止。
发射器的“生命周期”(工作周期)是从直行第一次开始,到close( )或者函数返回。此外,在第一次send( )之前需要调用一次next( )
import os import time def print_matches(key): print "Looking for,",key while True: line = (yield) if key in line: print line def tail(f): f.seek(0,os.SEEK_END) while True: line = f.readline() if not line: time.sleep(0.1) continue else: yield line matchers = [ print_matches("python"), print_matches("guido"), print_matches("jython") ] #在第一次使用一个coroutine之前,必须先调用一次next()函数 for m in matchers: m.next() wwwlog = tail(open("log")) for line in wwwlog: for m in matchers: m.send(line)
29、查看类(对象)的方法,Python的源代码中含有与javadoc类似的文档机制。
使用dir(类名/对象变量名),可以查看某类可用的方法,
特殊的方法,是两个下划线开始和结束的,如:__ne__,实际上是重载了操作符!=
如下:
>>> map = {"a":1,"b":2} >>> dir(map) ['__class__', '__cmp__', '__contains__', '__delattr__', '__delitem__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 'has_key', 'items', 'iteritems', 'iterkeys', 'itervalues', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values'] #__ne__是特殊函数,实际重载了!=操作符 >>> map.__ne__({"a":1,"b":2}) False >>> map != {"a":1,"b":2} False
这是一个很实用的技巧(我感觉Python的文档没有Javadoc那么详细)。
30、class里的类函数(相当于c++的static函数)。
需要用@staticmethod标记,如下:
#!/usr/bin/python class TestClass: #注意:static函数无需self参数 @staticmethod def print_static(): print("I'm an static function.") def print_non_static(self): print("I'm not an static function.") if __name__ == "__main__": TestClass.print_static() tc = TestClass() tc.print_non_static()
31、异常处理方法为:的try、catch:
#!/usr/bin/python try: f = open("file.txt","r") except IOError as e: print e finally: print "Finally release other resource."
(2)使用with语句:
主动抛出异常用raise:
raise RuntimeError("Computer says no")
32、除了finally之外,还可以使用with来自动释放资源:
with m_lock: message.add(msg)
with操作符由lock重载过了,当进入with时候,会锁住临界区,出with块后会释放锁。
33、关于简单的doc。
在函数下面用三引号定义的,可以用doc函数(或者函数名.__doc__)取出,如下:
def TestFunction(): """ I'm the doc for TestFunction. """ print("Do nothing.") if __name__ == "__main__": TestFunction() #可以用__doc__取出。 >>> TestFunction.__doc__ "\n I'm the doc for TestFunction.\n "
(第一章笔记完)