命令行
命令行可以運(yùn)行Python程序叮称。通過使用:python xxx.py
如果想要加上一些參數(shù):參考鏈接
在Python命令行中下劃線有特殊的作用,代表前一個(gè)計(jì)算出的結(jié)果。
聲明文件編碼:
# coding=utf-8
計(jì)算器
關(guān)于隱式類型轉(zhuǎn)換需要注意。
計(jì)算符號(hào)需要注意,不會(huì)可參考下面的代碼:
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
變量必須在聲明時(shí)賦值冲九,與此同時(shí)會(huì)確定類型。
字符串
單引號(hào)和雙引號(hào)都能表示字符串跟束。區(qū)別在于轉(zhuǎn)義的時(shí)候莺奸。
如果懶得加轉(zhuǎn)義字符,可以通過在字符串前面加上r冀宴。例如:
print r'C:\some\name'
通過在字符串里面添加反斜杠來不換行灭贷。
print """\
Usage: thingy [OPTIONS]
-h Display this usage message
-H hostname Hostname to connect to
"""
字符串通過加號(hào)來連接,并可以通過乘號(hào)來翻倍略贮。
字符串也可以通過寫在一起來連接,但是不能用在變量上面:
'Py' 'thon'
字符串可以像數(shù)組一樣訪問氧腰,0代表開始字符。特別的是刨肃,-1代表最后一個(gè)字符古拴,-2表示倒數(shù)第2個(gè)字符,依次得到結(jié)果真友。
字符串可以切片訪問黄痪。比較特別的是使用負(fù)數(shù)來切片。
s="abcde"
s[0]
s[-1]
s[-5]
s[:-1] #去掉最后一個(gè)字符盔然,比如換行符
+---+---+---+---+---+---+
| P | y | t | h | o | n |
+---+---+---+---+---+---+
0 1 2 3 4 5 6
-6 -5 -4 -3 -2 -1
切片訪問越界會(huì)得到一個(gè)空集桅打。無需做訪問控制。
對(duì)于單個(gè)字符時(shí)無法賦值的愈案,因?yàn)樽址遣豢勺兊耐ξ病H绻枰粋€(gè)不同的字符串,那就creat一個(gè)新的字符串吧站绪,使用切片能夠很容易達(dá)到這點(diǎn)遭铺。
內(nèi)置函數(shù)len返回字符串的長度。
用encode和decode來問字符串編碼解碼。(關(guān)于編碼類型的問題魂挂,需要專門開一個(gè)文件來討論)
list列表
list與string差不多甫题,兩者區(qū)別在于,list可以修改涂召,string不可以坠非。
list可以嵌套,并且可以通過二維引用去取值果正,不要忘記這個(gè)特性炎码。
編程特性
看下面的例子:
a, b = 0, 1
while b < 10:
print b
a, b = b, a+b
Python支持多重賦值,很有意思的一點(diǎn)秋泳。
while語句的條件無需括號(hào)辅肾,簡化了。條件符號(hào)包含:> < == <= >=
循環(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)
注意:在遍歷的時(shí)候同時(shí)修改待遍歷的list是危險(xiǎn)的(考慮不斷在list后面加的情況)。
因此需要遍歷的時(shí)候舍杜,使用切片返回一個(gè)list副本將會(huì)是一個(gè)安全的作法新娜。
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'
是的饲握,沒有看錯(cuò)私杜,else是給for用的。
表達(dá)的意思是指救欧,如果for不是break退出的衰粹,則運(yùn)行else。
pass語句代表空語句笆怠,用來占位用的铝耻。
定義函數(shù)
Python的函數(shù)不需要返回值類型。
函數(shù)定義之后可以作為變量賦值蹬刷。
如果一個(gè)函數(shù)沒有返回值瓢捉,那么會(huì)返回一個(gè)None。如果需要返回值办成,顯示的return泡态。
一個(gè)典型的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è)置默認(rèn)值,形如:
def ask_ok(prompt, retries=4, complaint='Yes or no, please!')
有關(guān)默認(rèn)值迂卢,需要注意的是某弦,如果給可變數(shù)據(jù)的類型如list設(shè)置默認(rèn)值為空桐汤,那么再次調(diào)用此函數(shù)會(huì)使用之前的那個(gè)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]
這當(dāng)然不是我們想要的結(jié)果刀崖。所以正確的作法是應(yīng)該寫成None:
def f(a, L=None):
if L is None:
L = []
L.append(a)
return L
當(dāng)然惊科,Python很靈活拍摇,提供你在調(diào)用函數(shù)的時(shí)候使用關(guān)鍵詞來給出參數(shù):
parrot(voltage=1000)
但是靈活不代表沒有規(guī)則亮钦,關(guān)于參數(shù),需要嚴(yán)格按照函數(shù)的需要來給出充活。沒有默認(rèn)值的要給出參數(shù)值蜂莉,如果不指明關(guān)鍵詞,那么將會(huì)按照順序讀取你的參數(shù)混卵。
對(duì)于較為復(fù)雜的函數(shù)參數(shù)映穗,建議還是輸入關(guān)鍵詞為好。避免出現(xiàn)不必要的錯(cuò)誤幕随。
來看一個(gè)比較復(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
星號(hào)name 必須在 double星號(hào)name 之前蚁滋。
星號(hào)name接受多個(gè)無關(guān)鍵詞的參數(shù)。
double接受有關(guān)鍵詞的參數(shù)赘淮。
double星號(hào)name 其實(shí)就是一個(gè)元組辕录。傳遞時(shí)使用double星號(hào)
lambda表達(dá)式
也就是一個(gè)函數(shù),運(yùn)行時(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')]
注釋
單行注釋是#
多行注釋為三個(gè)雙引號(hào)nothing三個(gè)雙引號(hào),關(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.
編程風(fēng)格
寫的多自然就懂了
數(shù)據(jù)存儲(chǔ)細(xì)節(jié)
more on lists
list對(duì)象提供了很多方法可以使用,比如說下面這些:
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當(dāng)做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當(dāng)做隊(duì)列來用
比如下面:
>>> 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ù)編程工具
有三個(gè)非常有用的內(nèi)建函數(shù):filter()蛤高、map()蚣旱、reduce()
filter(function, sequence)返回一個(gè)篩選過后的列表。
>>> 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)對(duì)于每一個(gè)在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)返回一個(gè)單一的值。與map不同恤批,map返回的是一個(gè)list列表位隶。
reduce其實(shí)就是把前一輪計(jì)算的值作為參數(shù),繼續(xù)進(jìn)行下一輪的計(jì)算开皿。
>>> def add(x,y): return x+y
...
>>> reduce(add, range(1, 11))
55
reduce還有第三個(gè)參數(shù)涧黄,用來設(shè)置輪回的初始值:
>>> def sum(seq):
... def add(x,y): return x+y
... return reduce(add, seq, 0)
...
>>> sum(range(1, 11))
55
>>> sum([])
0
列表推導(dǎo)
比如說,我們想要?jiǎng)?chuàng)建一個(gè)數(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)建方法其實(shí)是:
squares = [x**2 for x in range(10)]
#當(dāng)然用下面的lamda表達(dá)式也行
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)]
如果表達(dá)式里面有括弧笋妥,那么就肯定是一個(gè)元組啦:
>>> 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表達(dá)式能夠使用復(fù)雜的表達(dá)式,并且能夠嵌套函數(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']
列表推導(dǎo)嵌套
列表推導(dǎo)是能夠嵌套著來的窄潭,比如說:
>>> 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]]
#上面這個(gè)程序能夠把行列表轉(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]]
用哪個(gè)呢春宣?肯定是列表嵌套簡單明了啦,哈哈。
有沒有更好的方法呢月帝?當(dāng)然就是內(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的強(qiáng)大之處簸搞,在于支持切片刪除哦扁位。
>>> 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也能夠用來刪除整個(gè)變量:
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',)
如果想要初始化一個(gè)元組暇务,且是只有一個(gè)元素,為了單個(gè)元組賦值做區(qū)分怔软,后面加個(gè)逗號(hào)垦细。
元組的還支持拆分,比如說:
t=12345, 54321, 'hello!'
x, y, z = t
集合
集合一個(gè)容器爽雄,里面沒有重復(fù)的數(shù)據(jù)蝠检。典型的用途是消除重復(fù)數(shù)據(jù)。當(dāng)然也能用來測試是否存在重復(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'])
集合能做一些加減交并的操作叹谁。
類似列表推導(dǎo),集合也支持:
>>> a = {x for x in 'abracadabra' if x not in 'abc'}
>>> a
set(['r', 'd'])
集合推導(dǎo)用{}包住乘盖。不過我在command里面運(yùn)行出錯(cuò)焰檩,不知道什么原因。
字典
字典就是就是鍵值對(duì)類型的數(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è)列表構(gòu)建出一個(gè)序列:
>>> dict([('sape', 4139), ('guido', 4127), ('jack', 4098)])
{'sape': 4139, 'jack': 4098, 'guido': 4127}
當(dāng)然啦析苫,字典可以通過表達(dá)式來生成:
>>> {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ù)
當(dāng)要對(duì)一個(gè)序列做遍歷的時(shí)候哦穿扳,大概是這樣的:
>>> for i, v in enumerate(['tic', 'tac', 'toe']):
... print i, v
...
0 tic
1 tac
2 toe
如果想要循環(huán)的同時(shí)搞好幾個(gè)序列的話衩侥,用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
如果想要遍歷一個(gè)字典矛物,一般都要同時(shí)拿到key和value茫死,可以這么做:
>>> knights = {'gallahad': 'the pure', 'robin': 'the brave'}
>>> for k, v in knights.iteritems():
... print k, v
...
gallahad the pure
robin the brave
還是那個(gè)要注意的地方,如果需要遍歷的時(shí)候修改履羞,使用一個(gè)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']
條件表達(dá)式
有哪些條件表達(dá)式呢屡久?
簡單的符號(hào)自然不用講了:
in 和 not in:代表檢查元素是否在序列中
is 和 is not:檢查是否是同一個(gè)東西
and 和 or:代表與和或的邏輯
不用去記憶優(yōu)先級(jí),用括號(hào)吧爱榔,而且方便閱讀被环。
舉個(gè)例子:
>>> string1, string2, string3 = '', 'Trondheim', 'Hammer Dance'
>>> non_null = string1 or string2 or string3
>>> non_null
'Trondheim'
序列之間的比較是逐個(gè)進(jìn)行的:
(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里面一個(gè)模塊就是一個(gè)文件。
比如說下面這個(gè)模塊:
# 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
使用的時(shí)候得這樣:
>>> 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)常使用某個(gè)函數(shù)筛欢,完全可以這樣子:
>>> fib = fibo.fib
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377
更多的模塊
一般來說,使用模塊推薦的方式是導(dǎo)入固定的函數(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
使得模塊像腳本一樣運(yùn)行
像下面這樣:
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來自于:
運(yùn)行腳本所在的當(dāng)前目錄
PYTHONPATH環(huán)境變量
默認(rèn)的安裝依賴
編譯
這個(gè)暫時(shí)先不搞揣钦,等以后有需要開專題雳灾。
標(biāo)準(zhǔn)模塊
可以通過下面的命令去擴(kuò)展模塊搜索:
>>> import sys
>>> sys.path.append('/ufs/guido/lib/python')
dir函數(shù)
這個(gè)函數(shù)可以得到模塊提供的函數(shù)。
如果么有參數(shù)冯凹,會(huì)得到已經(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ù)等等。
導(dǎo)入和包
兩種導(dǎo)入方式:
import sound.effects.echo
import sound.effects.surround
from sound.effects import *
如何從一個(gè)包中導(dǎo)入所有模塊呢浑劳?阱持?
可以在包下面新建一個(gè)文件:init.py:
all__ = ["echo", "surround", "reverse"]
然后:from package import 星號(hào)
輸入輸出
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ù)打開文件并返回一個(gè)文件句柄蒜绽。形如:
>>> f = open('workfile', 'w')
>>> print f
<open file 'workfile', mode 'w' at 80a0960>
關(guān)于文件的打開模式:
- r是只可讀
- w是覆蓋寫
- a是寫追加
- r+代表可讀可覆蓋寫
- a+代表可讀可追加
還有一些二進(jìn)制文件的讀寫方式r+b镶骗,不夠暫時(shí)用不上。
file對(duì)象可以通過read讀取躲雅,通過readline逐行讀取鼎姊。
每次讀取后,文件指針都會(huì)便宜相赁,以此實(shí)現(xiàn)對(duì)文件的遍歷相寇。
>>> 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()唤衫。
文件寫只有一個(gè)方法write。此外跺嗽,通過seek函數(shù)可以偏移文件讀取指針战授。
在文件讀寫完畢之后页藻,記得close:
f.close()
讀取文件無比采用下面的模型,相當(dāng)于try-except:
>>> with open('workfile', 'r') as f:
... read_data = f.read()
>>> f.closed
True
JSON
Python支持JSON的編碼解碼。具體請(qǐng)看:JSON
錯(cuò)誤和異常
如果程序運(yùn)行時(shí)出錯(cuò)植兰,會(huì)拋出異常份帐,然后程序就終止了。
有的時(shí)候終止不是我們想看到的楣导,那么可以用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..."
...
下面是比較標(biāo)準(zhǔn)的異常錯(cuò)誤處理方式:
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 會(huì)把異常往上拋出,一般來說會(huì)導(dǎo)致程序終止筒繁。
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!'
或者看這個(gè):
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'
推薦方式
下面這種方式訪問文件時(shí)被推薦的,因?yàn)樽詭Я薴inal處理:
with open("myfile.txt") as f:
for line in f:
print line,
類
下面定義一個(gè)最簡單的類:
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)
實(shí)例對(duì)象
這方面很像c++了毡咏,無需贅述驮宴。
方法對(duì)象
方法也是一個(gè)對(duì)象。因此可以做到賦值操作:
xf = x.f
while True:
print xf()
類和對(duì)象屬性
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'
在方法外的類屬性呕缭,相當(dāng)于其他語言的全局變量堵泽,這意味著,不同對(duì)象會(huì)共享這個(gè)變量(列表或者字典)
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)
這不是一個(gè)好做法恢总。至少在你完全掌握之前迎罗。
正確的做法是:
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)
繼承
如果想要繼承一個(gè)類,這樣寫就好了:
class DerivedClassName(modname.BaseClassName):
有下面兩個(gè)函數(shù):
- isinstance(obj, int) 將會(huì)判斷obj是否為int類型
- issubclass(bool, int)將會(huì)判斷是否為子類
多重繼承
class DerivedClassName(Base1, Base2, Base3):
私有屬性
雙重下劃線所標(biāo)示的屬性是私有屬性片仿。
異常也是類
前面講過了
迭代器
前面看到的迭代器大多是這樣的::
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,
其實(shí)有專門的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
生成器
一個(gè)例子
def reverse(data):
for index in range(len(data)-1, -1, -1):
yield data[index]
for char in reverse('golf'):
print char
生成器表達(dá)式
很有用,但是可讀性比較差砂豌。