命令行
命令行可以運行Python程序。通過使用:python xxx.py
如果想要加上一些參數(shù):參考鏈接
在Python命令行中下劃線有特殊的作用,代表前一個計算出的結(jié)果。
聲明文件編碼:
# coding=utf-8
計算器
關(guān)于隱式類型轉(zhuǎn)換需要注意。
計算符號需要注意,不會可參考下面的代碼:
17 / 3.0 # int / float -> float
17 // 3.0 # explicit floor division discards the fractional part
5.0
17 % 3 # the % operator returns the remainder of the division
2
5 ** 2 # 5 squared
25
2 ** 7 # 2 to the power of 7
128
變量必須在聲明時賦值,與此同時會確定類型。
字符串
單引號和雙引號都能表示字符串。區(qū)別在于轉(zhuǎn)義的時候。
如果懶得加轉(zhuǎn)義字符,可以通過在字符串前面加上r。例如:
print r'C:\some\name'
通過在字符串里面添加反斜杠來不換行。
print """\
Usage: thingy [OPTIONS]
-h Display this usage message
-H hostname Hostname to connect to
"""
字符串通過加號來連接,并可以通過乘號來翻倍。
字符串也可以通過寫在一起來連接,但是不能用在變量上面:
'Py' 'thon'
字符串可以像數(shù)組一樣訪問,0代表開始字符。特別的是,-1代表最后一個字符,-2表示倒數(shù)第2個字符,依次得到結(jié)果。
字符串可以切片訪問。比較特別的是使用負數(shù)來切片。
s="abcde"
s[0]
s[-1]
s[-5]
s[:-1] #去掉最后一個字符,比如換行符
+---+---+---+---+---+---+
| P | y | t | h | o | n |
+---+---+---+---+---+---+
0 1 2 3 4 5 6
-6 -5 -4 -3 -2 -1
切片訪問越界會得到一個空集。無需做訪問控制。
對于單個字符時無法賦值的,因為字符串是不可變的。如果需要一個不同的字符串,那就creat一個新的字符串吧,使用切片能夠很容易達到這點。
內(nèi)置函數(shù)len返回字符串的長度。
用encode和decode來問字符串編碼解碼。(關(guān)于編碼類型的問題,需要專門開一個文件來討論)
list列表
list與string差不多,兩者區(qū)別在于,list可以修改,string不可以。
list可以嵌套,并且可以通過二維引用去取值,不要忘記這個特性。
編程特性
看下面的例子:
a, b = 0, 1
while b < 10:
print b
a, b = b, a+b
Python支持多重賦值,很有意思的一點。
while語句的條件無需括號,簡化了。條件符號包含:> < == <= >=
循環(huán)控制工具
除了wihle還有一些循環(huán)和控制語句。
比如說if語句:
if x < 0:
x = 0
print 'Negative changed to zero'
elif x == 0:
print 'Zero'
elif x == 1:
print 'Single'
else:
print 'More'
for循環(huán)與while循環(huán)是不同的,更多用于遍歷:
words = ['cat', 'window', 'defenestrate']
for w in words:
print w, len(w)
注意:在遍歷的時候同時修改待遍歷的list是危險的(考慮不斷在list后面加的情況)。
因此需要遍歷的時候,使用切片返回一個list副本將會是一個安全的作法。
for w in words[:]:
if len(w) > 6:
words.insert(0, w)
如果需要返回一串順序的數(shù)字list,可以用range:
range(10)
range(5, 10)
range(0, 10, 3)=[0, 3, 6, 9]
range(-10, -100, -30)=[-10, -40, -70]
由于range的存在,可以使用下面這種方法遍歷list:
a = ['Mary', 'had', 'a', 'little', 'lamb']
for i in range(len(a)):
print i, a[i]
break和continue不用多說,但是循環(huán)加上else還是挺有意思的。
for n in range(2, 10):
for x in range(2, n):
if n % x == 0:
print n, 'equals', x, '*', n/x
else:
print n, 'is a prime number'
是的,沒有看錯,else是給for用的。
表達的意思是指,如果for不是break退出的,則運行else。
pass語句代表空語句,用來占位用的。
定義函數(shù)
Python的函數(shù)不需要返回值類型。
函數(shù)定義之后可以作為變量賦值。
如果一個函數(shù)沒有返回值,那么會返回一個None。如果需要返回值,顯示的return。
一個典型的python是想下面這樣的:
def fib2(n):
result = []
a, b = 0, 1
while a < n:
result.append(a) # see below
a,b=b,a+b
return result
更多有關(guān)函數(shù)定義
Python的函數(shù)參數(shù)可以設(shè)置默認值,形如:
def ask_ok(prompt, retries=4, complaint='Yes or no, please!')
有關(guān)默認值,需要注意的是,如果給可變數(shù)據(jù)的類型如list設(shè)置默認值為空,那么再次調(diào)用此函數(shù)會使用之前的那個list而不是空。比如:
def f(a, L=[]):
L.append(a)
return L
print f(1)
print f(2)
print f(3)
[1]
[1, 2]
[1, 2, 3]
這當然不是我們想要的結(jié)果。所以正確的作法是應(yīng)該寫成None:
def f(a, L=None):
if L is None:
L = []
L.append(a)
return L
當然,Python很靈活,提供你在調(diào)用函數(shù)的時候使用關(guān)鍵詞來給出參數(shù):
parrot(voltage=1000)
但是靈活不代表沒有規(guī)則,關(guān)于參數(shù),需要嚴格按照函數(shù)的需要來給出。沒有默認值的要給出參數(shù)值,如果不指明關(guān)鍵詞,那么將會按照順序讀取你的參數(shù)。
對于較為復(fù)雜的函數(shù)參數(shù),建議還是輸入關(guān)鍵詞為好。避免出現(xiàn)不必要的錯誤。
來看一個比較復(fù)雜的函數(shù)參數(shù)例子:
def cheeseshop(kind, *arguments, **keywords):
print "-- Do you have any", kind, "?"
print "-- I'm sorry, we're all out of", kind
for arg in arguments:
print arg
print "-" * 40
keys = sorted(keywords.keys())
for kw in keys:
print kw, ":", keywords[kw]
cheeseshop("Limburger", "It's very runny, sir.",
"It's really very, VERY runny, sir.",
shopkeeper='Michael Palin',
client="John Cleese",
sketch="Cheese Shop Sketch")
-- Do you have any Limburger ?
-- I'm sorry, we're all out of Limburger
It's very runny, sir.
It's really very, VERY runny, sir.
----------------------------------------
client : John Cleese
shopkeeper : Michael Palin
sketch : Cheese Shop Sketch
星號name 必須在 double星號name 之前。
星號name接受多個無關(guān)鍵詞的參數(shù)。
double接受有關(guān)鍵詞的參數(shù)。
double星號name 其實就是一個元組。傳遞時使用double星號
lambda表達式
也就是一個函數(shù),運行時才確定函數(shù)執(zhí)行的屬性和方法。形如:
def make_incrementor(n):
return lambda x: x + n
f = make_incrementor(42)
f(0)=42
f(1)=43
pairs = [(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four')]
pairs.sort(key=lambda pair: pair[1])
pairs=[(4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')]
注釋
單行注釋是#
多行注釋為三個雙引號nothing三個雙引號,關(guān)于多行注釋,注意形如:
def my_function():
"""Do noting
no real do nothing
"""
pass
print my_function.__doc__
Do nothing, but document it.
No, really, it doesn't do anything.
編程風格
寫的多自然就懂了
數(shù)據(jù)存儲細節(jié)
more on lists
list對象提供了很多方法可以使用,比如說下面這些:
list.append(x)
Add an item to the end of the list; equivalent to a[len(a):] = [x].list.extend(L)
Extend the list by appending all the items in the given list; equivalent to a[len(a):] = L.list.insert(i, x)
Insert an item at a given position. The first argument is the index of the element before which to insert, so a.insert(0, x) inserts at the front of the list, and a.insert(len(a), x) is equivalent to a.append(x).list.remove(x)
Remove the first item from the list whose value is x. It is an error if there is no such item.list.pop([i])
Remove the item at the given position in the list, and return it. If no index is specified, a.pop() removes and returns the last item in the list. (The square brackets around the i in the method signature denote that the parameter is optional, not that you should type square brackets at that position. You will see this notation frequently in the Python Library Reference.)list.index(x)
Return the index in the list of the first item whose value is x. It is an error if there is no such item.list.count(x)
Return the number of times x appears in the list.list.sort(cmp=None, key=None, reverse=False)
Sort the items of the list in place (the arguments can be used for sort customization, see sorted() for their explanation).list.reverse()
Reverse the elements of the list, in place.
例子如下所示:
>>> a = [66.25, 333, 333, 1, 1234.5]
>>> print a.count(333), a.count(66.25), a.count('x')
2 1 0
>>> a.insert(2, -1)
>>> a.append(333)
>>> a
[66.25, 333, -1, 333, 1, 1234.5, 333]
>>> a.index(333)
1
>>> a.remove(333)
>>> a
[66.25, -1, 333, 1, 1234.5, 333]
>>> a.reverse()
>>> a
[333, 1234.5, 1, 333, -1, 66.25]
>>> a.sort()
>>> a
[-1, 1, 66.25, 333, 333, 1234.5]
>>> a.pop()
1234.5
>>> a
[-1, 1, 66.25, 333, 333]
把list當做stack來用
比如下面:
>>> stack = [3, 4, 5]
>>> stack.append(6)
>>> stack.append(7)
>>> stack
[3, 4, 5, 6, 7]
>>> stack.pop()
7
>>> stack
[3, 4, 5, 6]
>>> stack.pop()
6
>>> stack.pop()
5
>>> stack
[3, 4]
把list當做隊列來用
比如下面:
>>> from collections import deque
>>> queue = deque(["Eric", "John", "Michael"])
>>> queue.append("Terry") # Terry arrives
>>> queue.append("Graham") # Graham arrives
>>> queue.popleft() # The first to arrive now leaves
'Eric'
>>> queue.popleft() # The second to arrive now leaves
'John'
>>> queue # Remaining queue in order of arrival
deque(['Michael', 'Terry', 'Graham'])
函數(shù)編程工具
有三個非常有用的內(nèi)建函數(shù):filter()、map()、reduce()
filter(function, sequence)返回一個篩選過后的列表。
>>> def f(x): return x % 3 == 0 or x % 5 == 0
...
>>> filter(f, range(2, 25))
[3, 5, 6, 9, 10, 12, 15, 18, 20, 21, 24]
map(function, sequence)對于每一個在sequence內(nèi)的元素,調(diào)用function。
>>> def cube(x): return x*x*x
...
>>> map(cube, range(1, 11))
[1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]
reduce(function, sequence)返回一個單一的值。與map不同,map返回的是一個list列表。
reduce其實就是把前一輪計算的值作為參數(shù),繼續(xù)進行下一輪的計算。
>>> def add(x,y): return x+y
...
>>> reduce(add, range(1, 11))
55
reduce還有第三個參數(shù),用來設(shè)置輪回的初始值:
>>> def sum(seq):
... def add(x,y): return x+y
... return reduce(add, seq, 0)
...
>>> sum(range(1, 11))
55
>>> sum([])
0
列表推導
比如說,我們想要創(chuàng)建一個數(shù)據(jù)平方的列表:
>>> squares = []
>>> for x in range(10):
... squares.append(x**2)
...
>>> squares
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
更簡便直接的創(chuàng)建方法其實是:
squares = [x**2 for x in range(10)]
#當然用下面的lamda表達式也行
squares = map(lambda x: x**2, range(10))
列表表示完全可以寫的更加復(fù)雜,比如說:
>>> [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]
#這等于:
>>> combs = []
>>> for x in [1,2,3]:
... for y in [3,1,4]:
... if x != y:
... combs.append((x, y))
...
>>> combs
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]
如果表達式里面有括弧,那么就肯定是一個元組啦:
>>> vec = [-4, -2, 0, 2, 4]
>>> # create a new list with the values doubled
>>> [x*2 for x in vec]
[-8, -4, 0, 4, 8]
>>> # filter the list to exclude negative numbers
>>> [x for x in vec if x >= 0]
[0, 2, 4]
>>> # apply a function to all the elements
>>> [abs(x) for x in vec]
[4, 2, 0, 2, 4]
>>> # call a method on each element
>>> freshfruit = [' banana', ' loganberry ', 'passion fruit ']
>>> [weapon.strip() for weapon in freshfruit]
['banana', 'loganberry', 'passion fruit']
>>> # create a list of 2-tuples like (number, square)
>>> [(x, x**2) for x in range(6)]
[(0, 0), (1, 1), (2, 4), (3, 9), (4, 16), (5, 25)]
>>> # the tuple must be parenthesized, otherwise an error is raised
>>> [x, x**2 for x in range(6)]
File "<stdin>", line 1
[x, x**2 for x in range(6)]
^
SyntaxError: invalid syntax
>>> # flatten a list using a listcomp with two 'for'
>>> vec = [[1,2,3], [4,5,6], [7,8,9]]
>>> [num for elem in vec for num in elem]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
list表達式能夠使用復(fù)雜的表達式,并且能夠嵌套函數(shù):
>>> from math import pi
>>> [str(round(pi, i)) for i in range(1, 6)]
['3.1', '3.14', '3.142', '3.1416', '3.14159']
列表推導嵌套
列表推導是能夠嵌套著來的,比如說:
>>> matrix = [
... [1, 2, 3, 4],
... [5, 6, 7, 8],
... [9, 10, 11, 12],
... ]
>>> [[row[i] for row in matrix] for i in range(4)]
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
#上面這個程序能夠把行列表轉(zhuǎn)為列列表
上面的程序等同于下面:
>>> transposed = []
>>> for i in range(4):
... transposed.append([row[i] for row in matrix])
...
>>> transposed
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
也等于下面:
>>> transposed = []
>>> for i in range(4):
... # the following 3 lines implement the nested listcomp
... transposed_row = []
... for row in matrix:
... transposed_row.append(row[i])
... transposed.append(transposed_row)
...
>>> transposed
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
用哪個呢?肯定是列表嵌套簡單明了啦,哈哈。
有沒有更好的方法呢?當然就是內(nèi)建函數(shù)啦,這種函數(shù)都經(jīng)過優(yōu)化,效率什么的都是杠杠的。
>>> zip(*matrix)
[(1, 5, 9), (2, 6, 10), (3, 7, 11), (4, 8, 12)]
del語句
除了list的remove之外,還有一種方法:del 能夠刪除list的元素。del的強大之處,在于支持切片刪除哦。
>>> a = [-1, 1, 66.25, 333, 333, 1234.5]
>>> del a[0]
>>> a
[1, 66.25, 333, 333, 1234.5]
>>> del a[2:4]
>>> a
[1, 66.25, 1234.5]
>>> del a[:]
>>> a
[]
del也能夠用來刪除整個變量:
del a
元組和序列
talk is cheap,關(guān)于元組,看下面的例子:
>>> t = 12345, 54321, 'hello!'
>>> t[0]
12345
>>> t
(12345, 54321, 'hello!')
>>> # Tuples may be nested:
... u = t, (1, 2, 3, 4, 5)
>>> u
((12345, 54321, 'hello!'), (1, 2, 3, 4, 5))
>>> # Tuples are immutable:
... t[0] = 88888
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> # but they can contain mutable objects:
... v = ([1, 2, 3], [3, 2, 1])
>>> v
([1, 2, 3], [3, 2, 1])
元組的普通元素是不能修改的。但是元組內(nèi)的list可以修改。
關(guān)于元組的一些特性,可以看下面:
>>> empty = ()
>>> singleton = 'hello', # <-- note trailing comma
>>> len(empty)
0
>>> len(singleton)
1
>>> singleton
('hello',)
如果想要初始化一個元組,且是只有一個元素,為了單個元組賦值做區(qū)分,后面加個逗號。
元組的還支持拆分,比如說:
t=12345, 54321, 'hello!'
x, y, z = t
集合
集合一個容器,里面沒有重復(fù)的數(shù)據(jù)。典型的用途是消除重復(fù)數(shù)據(jù)。當然也能用來測試是否存在重復(fù)數(shù)據(jù)。
看code:
>>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']
>>> fruit = set(basket) # create a set without duplicates
>>> fruit
set(['orange', 'pear', 'apple', 'banana'])
>>> 'orange' in fruit # fast membership testing
True
>>> 'crabgrass' in fruit
False
>>> # Demonstrate set operations on unique letters from two words
...
>>> a = set('abracadabra')
>>> b = set('alacazam')
>>> a # unique letters in a
set(['a', 'r', 'b', 'c', 'd'])
>>> a - b # letters in a but not in b
set(['r', 'd', 'b'])
>>> a | b # letters in either a or b
set(['a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'])
>>> a & b # letters in both a and b
set(['a', 'c'])
>>> a ^ b # letters in a or b but not both
set(['r', 'd', 'b', 'm', 'z', 'l'])
集合能做一些加減交并的操作。
類似列表推導,集合也支持:
>>> a = {x for x in 'abracadabra' if x not in 'abc'}
>>> a
set(['r', 'd'])
集合推導用{}包住。不過我在command里面運行出錯,不知道什么原因。
字典
字典就是就是鍵值對類型的數(shù)據(jù)集合。大概是下面這樣的:
>>> tel = {'jack': 4098, 'sape': 4139}
>>> tel['guido'] = 4127
>>> tel
{'sape': 4139, 'guido': 4127, 'jack': 4098}
>>> tel['jack']
4098
>>> del tel['sape']
>>> tel['irv'] = 4127
>>> tel
{'guido': 4127, 'irv': 4127, 'jack': 4098}
>>> tel.keys()
['guido', 'irv', 'jack']
>>> 'guido' in tel
True
dic函數(shù)通過一個列表構(gòu)建出一個序列:
>>> dict([('sape', 4139), ('guido', 4127), ('jack', 4098)])
{'sape': 4139, 'jack': 4098, 'guido': 4127}
當然啦,字典可以通過表達式來生成:
>>> {x: x**2 for x in (2, 4, 6)}
{2: 4, 4: 16, 6: 36}
如果key是簡單字符串的話,更加容易訪問:
>>> dict(sape=4139, guido=4127, jack=4098)
{'sape': 4139, 'jack': 4098, 'guido': 4127}
循環(huán)技術(shù)
當要對一個序列做遍歷的時候哦,大概是這樣的:
>>> for i, v in enumerate(['tic', 'tac', 'toe']):
... print i, v
...
0 tic
1 tac
2 toe
如果想要循環(huán)的同時搞好幾個序列的話,用zip函數(shù):
>>> questions = ['name', 'quest', 'favorite color']
>>> answers = ['lancelot', 'the holy grail', 'blue']
>>> for q, a in zip(questions, answers):
... print 'What is your {0}? It is {1}.'.format(q, a)
...
What is your name? It is lancelot.
What is your quest? It is the holy grail.
What is your favorite color? It is blue.
如果想要逆序,這樣子來:
>>> for i in reversed(xrange(1,10,2)):
... print i
...
9
7
5
3
1
想要遍歷排序之后的話:
>>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']
>>> for f in sorted(set(basket)):
... print f
...
apple
banana
orange
pear
如果想要遍歷一個字典,一般都要同時拿到key和value,可以這么做:
>>> knights = {'gallahad': 'the pure', 'robin': 'the brave'}
>>> for k, v in knights.iteritems():
... print k, v
...
gallahad the pure
robin the brave
還是那個要注意的地方,如果需要遍歷的時候修改,使用一個copy。
>>> words = ['cat', 'window', 'defenestrate']
>>> for w in words[:]: # Loop over a slice copy of the entire list.
... if len(w) > 6:
... words.insert(0, w)
...
>>> words
['defenestrate', 'cat', 'window', 'defenestrate']
條件表達式
有哪些條件表達式呢?
簡單的符號自然不用講了:
in 和 not in:代表檢查元素是否在序列中
is 和 is not:檢查是否是同一個東西
and 和 or:代表與和或的邏輯
不用去記憶優(yōu)先級,用括號吧,而且方便閱讀。
舉個例子:
>>> string1, string2, string3 = '', 'Trondheim', 'Hammer Dance'
>>> non_null = string1 or string2 or string3
>>> non_null
'Trondheim'
序列之間的比較是逐個進行的:
(1, 2, 3) < (1, 2, 4)
[1, 2, 3] < [1, 2, 4]
'ABC' < 'C' < 'Pascal' < 'Python'
(1, 2, 3, 4) < (1, 2, 4)
(1, 2) < (1, 2, -1)
(1, 2, 3) == (1.0, 2.0, 3.0)
(1, 2, ('aa', 'ab')) < (1, 2, ('abc', 'a'), 4)
模塊
Python里面一個模塊就是一個文件。
比如說下面這個模塊:
# Fibonacci numbers module
def fib(n): # write Fibonacci series up to n
a, b = 0, 1
while b < n:
print b,
a, b = b, a+b
def fib2(n): # return Fibonacci series up to n
result = []
a, b = 0, 1
while b < n:
result.append(b)
a, b = b, a+b
return result
使用的時候得這樣:
>>> import fibo
>>> fibo.fib(1000)
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
>>> fibo.fib2(100)
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
>>> fibo.__name__
'fibo'
通過調(diào)用name可以得到模塊名稱。
如果你經(jīng)常使用某個函數(shù),完全可以這樣子:
>>> fib = fibo.fib
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377
更多的模塊
一般來說,使用模塊推薦的方式是導入固定的函數(shù),如下所示:
>>> from fibo import fib, fib2
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377
或者:
>>> from fibo import *
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377
使得模塊像腳本一樣運行
像下面這樣:
python fibo.py <arguments>
if __name__ == "__main__":
import sys
fib(int(sys.argv[1]))
$ python fibo.py 50
1 1 2 3 5 8 13 21 34
模塊的搜索路徑
大致過程是:
- 搜索內(nèi)建模塊
- 搜索sys.path,sys.path來自于:
運行腳本所在的當前目錄
PYTHONPATH環(huán)境變量
默認的安裝依賴
編譯
這個暫時先不搞,等以后有需要開專題。
標準模塊
可以通過下面的命令去擴展模塊搜索:
>>> import sys
>>> sys.path.append('/ufs/guido/lib/python')
dir函數(shù)
這個函數(shù)可以得到模塊提供的函數(shù)。
如果么有參數(shù),會得到已經(jīng)定義的名字。
>>> import fibo, sys
>>> dir(fibo)
['__name__', 'fib', 'fib2']
>>> a = [1, 2, 3, 4, 5]
>>> import fibo
>>> fib = fibo.fib
>>> dir()
['__builtins__', '__name__', '__package__', 'a', 'fib', 'fibo', 'sys']
注意,列出來的東西包括所有名稱:變量、模塊、函數(shù)等等。
導入和包
兩種導入方式:
import sound.effects.echo
import sound.effects.surround
from sound.effects import *
如何從一個包中導入所有模塊呢??
可以在包下面新建一個文件:init.py:
all__ = ["echo", "surround", "reverse"]
然后:from package import 星號
輸入輸出
str和repr都能用來轉(zhuǎn)化數(shù)據(jù)位字符串。
repr面向解釋器,str面向人類可讀。
>>> s = 'Hello, world.'
>>> str(s)
'Hello, world.'
>>> repr(s)
"'Hello, world.'"
>>> str(1.0/7.0)
'0.142857142857'
>>> repr(1.0/7.0)
'0.14285714285714285'
>>> x = 10 * 3.25
>>> y = 200 * 200
>>> s = 'The value of x is ' + repr(x) + ', and y is ' + repr(y) + '...'
>>> print s
The value of x is 32.5, and y is 40000...
>>> # The repr() of a string adds string quotes and backslashes:
... hello = 'hello, world\n'
>>> hellos = repr(hello)
>>> print hellos
'hello, world\n'
>>> # The argument to repr() may be any Python object:
... repr((x, y, ('spam', 'eggs')))
"(32.5, 40000, ('spam', 'eggs'))"
下面有兩種方式格式化輸出:
>>> for x in range(1, 11):
... print repr(x).rjust(2), repr(x*x).rjust(3),
... # Note trailing comma on previous line
... print repr(x*x*x).rjust(4)
...
1 1 1
2 4 8
3 9 27
4 16 64
5 25 125
6 36 216
7 49 343
8 64 512
9 81 729
10 100 1000
>>> for x in range(1,11):
... print '{0:2d} {1:3d} {2:4d}'.format(x, x*x, x*x*x)
...
1 1 1
2 4 8
3 9 27
4 16 64
5 25 125
6 36 216
7 49 343
8 64 512
9 81 729
10 100 1000
str.format方法很好用,比如說:
>>> print 'We are the {} who say "{}!"'.format('knights', 'Ni')
We are the knights who say "Ni!"
>>> print '{0} and {1}'.format('spam', 'eggs')
spam and eggs
>>> print '{1} and {0}'.format('spam', 'eggs')
eggs and spam
>>> print 'This {food} is {adjective}.'.format(
... food='spam', adjective='absolutely horrible')
This spam is absolutely horrible.
>>> print 'The story of {0}, {1}, and {other}.'.format('Bill', 'Manfred',
... other='Georg')
The story of Bill, Manfred, and Georg.
#'!s' (apply str()) and '!r' (apply repr())
>>> import math
>>> print 'The value of PI is approximately {}.'.format(math.pi)
The value of PI is approximately 3.14159265359.
>>> print 'The value of PI is approximately {!r}.'.format(math.pi)
The value of PI is approximately 3.141592653589793.
>>> import math
>>> print 'The value of PI is approximately {0:.3f}.'.format(math.pi)
The value of PI is approximately 3.142.
>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 7678}
>>> for name, phone in table.items():
... print '{0:10} ==> {1:10d}'.format(name, phone)
...
Jack ==> 4098
Dcab ==> 7678
Sjoerd ==> 4127
>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678}
>>> print ('Jack: {0[Jack]:d}; Sjoerd: {0[Sjoerd]:d}; '
... 'Dcab: {0[Dcab]:d}'.format(table))
Jack: 4098; Sjoerd: 4127; Dcab: 8637678
>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678}
>>> print 'Jack: {Jack:d}; Sjoerd: {Sjoerd:d}; Dcab: {Dcab:d}'.format(**table)
Jack: 4098; Sjoerd: 4127; Dcab: 8637678
老式的字符串格式化
>>> import math
>>> print 'The value of PI is approximately %5.3f.' % math.pi
The value of PI is approximately 3.142.
讀寫文件
open函數(shù)打開文件并返回一個文件句柄。形如:
>>> f = open('workfile', 'w')
>>> print f
<open file 'workfile', mode 'w' at 80a0960>
關(guān)于文件的打開模式:
- r是只可讀
- w是覆蓋寫
- a是寫追加
- r+代表可讀可覆蓋寫
- a+代表可讀可追加
還有一些二進制文件的讀寫方式r+b,不夠暫時用不上。
file對象可以通過read讀取,通過readline逐行讀取。
每次讀取后,文件指針都會便宜,以此實現(xiàn)對文件的遍歷。
>>> for line in f:
print line,
This is the first line of the file.
Second line of the file
讀取到的字符串是包含換行符的。
如果想讀取文件的全部內(nèi)容,可以用:list(f) or f.readlines()。
文件寫只有一個方法write。此外,通過seek函數(shù)可以偏移文件讀取指針。
在文件讀寫完畢之后,記得close:
f.close()
讀取文件無比采用下面的模型,相當于try-except:
>>> with open('workfile', 'r') as f:
... read_data = f.read()
>>> f.closed
True
JSON
Python支持JSON的編碼解碼。具體請看:JSON
錯誤和異常
如果程序運行時出錯,會拋出異常,然后程序就終止了。
有的時候終止不是我們想看到的,那么可以用try-except捕獲異常。形如:
>>> while True:
... try:
... x = int(raw_input("Please enter a number: "))
... break
... except ValueError:
... print "Oops! That was no valid number. Try again..."
...
下面是比較標準的異常錯誤處理方式:
import sys
try:
f = open('myfile.txt')
s = f.readline()
i = int(s.strip())
except IOError as e:
print "I/O error({0}): {1}".format(e.errno, e.strerror)
except ValueError:
print "Could not convert data to an integer."
except:
print "Unexpected error:", sys.exc_info()[0]
raise
raise 會把異常往上拋出,一般來說會導致程序終止。
try-except還支持結(jié)尾加else,做用是為沒有定義的異常做統(tǒng)一的處理:
for arg in sys.argv[1:]:
try:
f = open(arg, 'r')
except IOError:
print 'cannot open', arg
else:
print arg, 'has', len(f.readlines()), 'lines'
f.close()
處理系統(tǒng)的異常之外,我們也可以自定義的拋出異常:
>>> try:
... raise Exception('spam', 'eggs')
... except Exception as inst:
... print type(inst) # the exception instance
... print inst.args # arguments stored in .args
... print inst # __str__ allows args to be printed directly
... x, y = inst.args
... print 'x =', x
... print 'y =', y
...
<type 'exceptions.Exception'>
('spam', 'eggs')
('spam', 'eggs')
x = spam
y = eggs
用戶也能夠自定義異常類
形如:
>>> class MyError(Exception):
... def __init__(self, value):
... self.value = value
... def __str__(self):
... return repr(self.value)
...
>>> try:
... raise MyError(2*2)
... except MyError as e:
... print 'My exception occurred, value:', e.value
...
My exception occurred, value: 4
>>> raise MyError('oops!')
Traceback (most recent call last):
File "<stdin>", line 1, in ?
__main__.MyError: 'oops!'
或者看這個:
class Error(Exception):
"""Base class for exceptions in this module."""
pass
class InputError(Error):
"""Exception raised for errors in the input.
Attributes:
expr -- input expression in which the error occurred
msg -- explanation of the error
"""
def __init__(self, expr, msg):
self.expr = expr
self.msg = msg
class TransitionError(Error):
"""Raised when an operation attempts a state transition that's not
allowed.
Attributes:
prev -- state at beginning of transition
next -- attempted new state
msg -- explanation of why the specific transition is not allowed
"""
def __init__(self, prev, next, msg):
self.prev = prev
self.next = next
self.msg = msg
異常清潔
就是最后加final啦:
>>> def divide(x, y):
... try:
... result = x / y
... except ZeroDivisionError:
... print "division by zero!"
... else:
... print "result is", result
... finally:
... print "executing finally clause"
...
>>> divide(2, 1)
result is 2
executing finally clause
>>> divide(2, 0)
division by zero!
executing finally clause
>>> divide("2", "1")
executing finally clause
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 3, in divide
TypeError: unsupported operand type(s) for /: 'str' and 'str'
推薦方式
下面這種方式訪問文件時被推薦的,因為自帶了final處理:
with open("myfile.txt") as f:
for line in f:
print line,
類
下面定義一個最簡單的類:
class Complex:
def init(self, realpart, imagpart):
self.r = realpart
self.i = imagpart
x = Complex(3.0, -4.5)
x.r, x.i
(3.0, -4.5)
實例對象
這方面很像c++了,無需贅述。
方法對象
方法也是一個對象。因此可以做到賦值操作:
xf = x.f
while True:
print xf()
類和對象屬性
class Dog:
kind = 'canine' # class variable shared by all instances
def __init__(self, name):
self.name = name # instance variable unique to each instance
>>> d = Dog('Fido')
>>> e = Dog('Buddy')
>>> d.kind # shared by all dogs
'canine'
>>> e.kind # shared by all dogs
'canine'
>>> d.name # unique to d
'Fido'
>>> e.name # unique to e
'Buddy'
在方法外的類屬性,相當于其他語言的全局變量,這意味著,不同對象會共享這個變量(列表或者字典)
class Dog:
tricks = [] # mistaken use of a class variable
def __init__(self, name):
self.name = name
def add_trick(self, trick):
self.tricks.append(trick)
這不是一個好做法。至少在你完全掌握之前。
正確的做法是:
class Dog:
def __init__(self, name):
self.name = name
self.tricks = [] # creates a new empty list for each dog
def add_trick(self, trick):
self.tricks.append(trick)
繼承
如果想要繼承一個類,這樣寫就好了:
class DerivedClassName(modname.BaseClassName):
有下面兩個函數(shù):
- isinstance(obj, int) 將會判斷obj是否為int類型
- issubclass(bool, int)將會判斷是否為子類
多重繼承
class DerivedClassName(Base1, Base2, Base3):
私有屬性
雙重下劃線所標示的屬性是私有屬性。
異常也是類
前面講過了
迭代器
前面看到的迭代器大多是這樣的::
for element in [1, 2, 3]:
print element
for element in (1, 2, 3):
print element
for key in {'one':1, 'two':2}:
print key
for char in "123":
print char
for line in open("myfile.txt"):
print line,
其實有專門的iter迭代器。
>>> s = 'abc'
>>> it = iter(s)
>>> it
<iterator object at 0x00A1DB50>
>>> it.next()
'a'
>>> it.next()
'b'
>>> it.next()
'c'
>>> it.next()
Traceback (most recent call last):
File "<stdin>", line 1, in ?
it.next()
StopIteration
生成器
一個例子
def reverse(data):
for index in range(len(data)-1, -1, -1):
yield data[index]
for char in reverse('golf'):
print char
生成器表達式
很有用,但是可讀性比較差。