简明 Python 教程
文章目錄
- 參考書籍
- 1、安裝和輸出
- 2、注釋
- 3、常量和變量
- 4、格式化方法
- 5、案例:使用變量與字面常量
- 6、運算符
- 7、數值運算與賦值的快捷方式
- 8、計算命令
- 9、if 語句
- 10、while 語句
- 11、for 循環
- 12、break 語句
- 13、continue 語句
- 14、函數
- 15、函數參數
- 16、局部變量
- 17、**global **語句
- 18、默認參數值
- 19、關鍵字參數
- 20、可變參數
- 21、return 語句
- 22、**DocStrings**
- 23、模塊
- 24、from..import 語句
- 25、模塊的 **__name__**
- 26、編寫你自己的模塊
- 27、dir 函數
- 28、包
- 29、數據結構
- 30、列表
- 31、元組
- 32、字典
- 33、序列
- 34、集合
- 35、引用
- 36、有關字符串的更多內容
- 37、問題-實現
- 38、問題-維護
- 39、問題-產生錯誤
- 40、問題-錯誤修復
- 41、問題-繼續改進
- 42、軟件開發流程
- 43、面向對象編程(面向高階讀者)
- 44、**self**
- 45、類
- 46、方法
- 47、__init__ 方法
- 48、類變量與對象變量
- 49、繼承
- 50、輸入與輸出
- 51、文件
- 52、**Pickle**
- 53、**Unicode**
- 54、錯誤異常
- 55、處理異常
- 56、拋出異常
- 57、**Try ... Finally**
- 58、with 語句
- 59、sys 模塊
- 60、日志模塊
- 61、更多-傳遞元組
- 62、更多-特殊方法
- 63、更多-單語句塊
- 64、更多-Lambda 表格
- 65、更多-列表推導
- 66、更多-在函數中接收元組與字典
- 67、更多-assert 語句
- 68、更多-裝飾器
- 69、邁出下一步
- 70、總結
參考書籍
1、安裝和輸出
1、官網:https://www.python.org/
2、Pycharm編輯器:https://www.jetbrains.com/zh-cn/pycharm/
3、輸出
2、注釋
print('hello world') #注意到 print 是一個函數 # 注意到 print 是一個函數 print('hello world') 你應該在你的程序中盡可能多地使用有用的注釋: 1)解釋假設 2)說明重要的決定 3)解釋重要的細節 4)說明你想要解決的問題 5)說明你想要在程序中克服的問題,等等。3、常量和變量
1、字面常量
2、數字:整數(Integers)與浮點數(Floats)
3、字符串:單引號、雙引號、三引號
4、格式化方法
age = 20 name = 'Swaroop' print('{0} was {1} years old when he wrote this book'.format(name, age)) print('Why is {0} playing with that python?'.format(name))name + 'is' +str(age) + 'years old # 對于浮點數 '0.333' 保留小數點(.)后三位 print('{0:.3f}'.format(1.0/3)) # 使用下劃線填充文本,并保持文字處于中間位置 # 使用 (^) 定義 '___hello___'字符串長度為 11 print('{0:_^11}'.format('hello')) # 基于關鍵詞輸出 'Swaroop wrote A Byte of Python' print('{name} wrote {book}'.format(name='Swaroop', book='A Byte of Python')) print('a', end='') print('b', end='')ab print('a', end=' ') print('b', end=' ') print('c')a b c5、案例:使用變量與字面常量
# 文件名:var.py i = 5 print(i) i = i + 1 print(i) s = '''This is a multi-line string. This is the second line.''' print(s)5 6 This is a multi-line string. This is the second line.6、運算符
+ (加) 兩個對象相加。 3+5 則輸出 8 。 'a' + 'b' 則輸出 'ab' 。- (減) 從一個數中減去另一個數,如果第一個操作數不存在,則假定為零。 -5.2 將輸出一個負數, 50 - 24 輸出 26 。* (乘) 給出兩個數的乘積,或返回字符串重復指定次數后的結果。 2 * 3 輸出 6 。 'la' * 3 輸出 'lalala' 。** (乘方) 返回 x 的 y 次方。 3 ** 4 輸出 81 (即 3 * 3 * 3 * 3 )。/ (除) x 除以 y 13 / 3 輸出 4.333333333333333 。// (整除) x 除以 y 并對結果向下取整至最接近的整數。 13 // 3 輸出 4 。 -13 // 3 輸出 -5 。% (取模) 返回除法運算后的余數。 13 % 3 輸出 1 。 -25.5 % 2.25 輸出 1.5 。<< (左移) 將數字的位向左移動指定的位數。(每個數字在內存中以二進制數表示,即 0 和1) 2 << 2 輸出 8 。 2 用二進制數表示為 10 。 向左移 2 位會得到 1000 這一結果,表示十進制中的 8 。>> (右移) 將數字的位向右移動指定的位數。 11 >> 1 輸出 5 。 11 在二進制中表示為 1011 ,右移一位后輸出 101 這一結果,表示十進制中的 5 。& (按位與) 對數字進行按位與操作。 5 & 3 輸出 1 。| (按位或) 對數字進行按位或操作。 5 | 3 輸出 7 。^ (按位異或) 對數字進行按位異或操作。 5 ^ 3 輸出 6 。~ (按位取反) x 的按位取反結果為 -(x+1)。 ~5 輸出 -6 。有關本例的更多細節可以參閱: http://stackoverflow.com/a/11810203。< (小于) 返回 x 是否小于 y。所有的比較運算符返回的結果均為 True 或 False 。請注意這些名稱之中的大寫字母。 5 < 3 輸出 False , 3 < 6 輸出 True 。 比較可以任意組成組成鏈接: 3 < 5 < 7 返回 True 。> (大于) 返回 x 是否大于 y。 5 > 3 返回 True 。如果兩個操作數均為數字,它們首先將會被轉換至一種共同的 類型。否則,它將總是返回 False 。<= (小于等于) 返回 x 是否小于或等于 y。 x = 3; y = 6; x<=y 返回 True 。>= (大于等于) 返回 x 是否大于或等于 y。 x = 4; y = 3; x>=3 返回 True 。== (等于) 比較兩個對象是否相等。 x = 2; y = 2; x == y 返回 True 。 x = 'str'; y = 'stR'; x == y 返回 False 。 x = 'str'; y = 'str'; x == y 返回 True 。!= (不等于) 比較兩個對象是否不相等。 x = 2; y = 3; x != y 返回 True 。not (布爾“非”) 如果 x 是 Ture ,則返回 False 。如果 x 是 False ,則返回 True 。 x = Ture; not x 返回 False 。and (布爾“與”) 如果 x 是 False ,則 x and y 返回 False ,否則返回 y 的計算值。 當 x 是 False 時, x = False; y = True; x and y 將返回 False 。在這一情境中, Python 將不會計算 y,因為它已經了解 and 表達式的左側是 False ,這意味著整個 表達式都將是 False 而不會是別的值。這種情況被稱作短路計算(Short-circuit Evaluation)。or (布爾“或”) 如果 x 是 True ,則返回 True ,否則它將返回 y 的計算值。 x = Ture; y = False; x or y 將返回 Ture 。在這里短路計算同樣適用。 1、按位與是針對二進制數的操作,指將兩個二進制數的每一位都進行比較,如果兩個相 應的二進位都為 1 則此位為 1,否則為 0。在本例中, 5 的二進制表達為 101 , 3 的 二進制表達為 11 (為補全位數進行按位操作寫作 011 ),則按位與操作后的結果為 001 ,對應的十進制數為 1 。 ?2、按位或是針對二進制數的操作,指將兩個二進制數的每一位都進行比較,如果兩個相 應的二進位有一個為 1 則此位為 1,否則為 0。在本例中, 101 與 011 進行按位或操 作后的結果為 111 ,對應十進制數為 7 。 ?3、按位異或是針對二進制數的操作,指將兩個二進制數的每一位都進行比較,如果兩個 相應的二進位不同則此位為 1,相同為 0。在本例中, 101 與 011 進行按位異或操作 的結果為 110 ,對應十進制數為 6 。 ?4、按位取反也稱作“按位取非”或“求非”或“取反”,沈潔元譯本譯作“按位翻轉”,是針對二進 制數的操作,指將兩個二進制數的每一二進位都進行取反操作, 0 換成 1 , 1 換成 0 。受篇幅與學識所限,本例具體原理不在此處贅述。讀者只需按照給出的公式記憶即 可。7、數值運算與賦值的快捷方式
a = 2 a = a * 3 變量 = 變量 運算 表達式 a = 2 a *= 3 會演變成 變量 運算 = 表達式8、計算命令
lambda :Lambda 表達式 if - else :條件表達式 or :布爾“或” and :布爾“與” not x :布爾“非” in, not in, is, is not, <, <=, >, >=, !=, == :比較,包括成員資格測試 (Membership Tests)和身份測試(Identity Tests)。 | :按位或 ^ :按位異或 & :按位與 <<, >> :移動 +, - :加與減 *, /, //, % :乘、除、整除、取余 +x, -x, ~x :正、負、按位取反 ** :求冪 x[index], x[index:index], x(arguments...), x.attribute :下標、切片、調用、屬性引用 (expressions...), [expressions...], {key: value...}, {expressions...} :顯示綁定或數組、顯示列表、顯示字典、顯示設置9、if 語句
number = 23 guess = int(input('Enter an integer : '))if guess == number:# 新塊從這里開始print('Congratulations, you guessed it.')print('(but you do not win any prizes!)')# 新塊在這里結束 elif guess < number:# 另一代碼塊print('No, it is a little higher than that')# 你可以在此做任何你希望在該代碼塊內進行的事情 else:print('No, it is a little lower than that')# 你必須通過猜測一個大于(>)設置數的數字來到達這里。print('Done') # 這最后一句語句將在 # if 語句執行完畢后執行。 $ python if.py Enter an integer : 50 No, it is a little lower than that Done$ python if.py Enter an integer : 22 No, it is a little higher than that Done$ python if.py Enter an integer : 23 Congratulations, you guessed it. (but you do not win any prizes!) Done10、while 語句
number = 23 running = Truewhile running:guess = int(input('Enter an integer : '))if guess == number:print('Congratulations, you guessed it.')# 這將導致 while 循環中止running = Falseelif guess < number:print('No, it is a little higher than that.')else:print('No, it is a little lower than that.') else:print('The while loop is over.')# 在這里你可以做你想做的任何事print('Done') $ python while.py Enter an integer : 50 No, it is a little lower than that. Enter an integer : 22 No, it is a little higher than that. Enter an integer : 23 Congratulations, you guessed it. The while loop is over. Done11、for 循環
for i in range(1, 5):print(i) else:print('The for loop is over')$ python for.py 1 2 3 4 The for loop is over for i in list(range(5)):print(i) else:print('The for loop is over')$ python for.py [0, 1, 2,3, 4] The for loop is over12、break 語句
while True:s = input('Enter something : ')if s == 'quit':breakprint('Length of the string is', len(s)) print('Done')$ python break.py Enter something : Programming is fun Length of the string is 18 Enter something : When the work is done Length of the string is 21 Enter something : if you wanna make your work also fun: Length of the string is 37 Enter something : use Python! Length of the string is 11 Enter something : quit Done13、continue 語句
while True:s = input('Enter something : ')if s == 'quit':breakif len(s) < 3:print('Too small')continueprint('Input is of sufficient length')# 自此處起繼續進行其它任何處理$ python continue.py Enter something : a Too small Enter something : 12 Too small Enter something : abc Input is of sufficient length Enter something : quit14、函數
def say_hello():# 該塊屬于這一函數print('hello world') # 函數結束say_hello() # 調用函數 say_hello() # 再次調用函數$ python function1.py hello world hello world15、函數參數
def print_max(a, b):if a > b:print(a, 'is maximum')elif a == b:print(a, 'is equal to', b)else:print(b, 'is maximum')# 直接傳遞字面值 print_max(3, 4)x = 5 y = 7# 以參數的形式傳遞變量 print_max(x, y)$ python function_param.py 4 is maximum 7 is maximum16、局部變量
x = 50 def func(x):print('x is', x)x = 2print('Changed local x to', x)func(x) print('x is still', x)$ python function_local.py x is 50 Changed local x to 2 x is still 5017、**global **語句
x = 50def func():global xprint('x is', x)x = 2print('Changed global x to', x)func() print('Value of x is', x)$ python function_global.py x is 50 Changed global x to 2 Value of x is 218、默認參數值
def say(message, times=1):print(message * times)say('Hello') say('World', 5)$ python function_default.py Hello WorldWorldWorldWorldWorld19、關鍵字參數
def func(a, b=5, c=10):print('a is', a, 'and b is', b, 'and c is', c)func(3, 7) func(25, c=24) func(c=50, a=100)$ python function_keyword.py a is 3 and b is 7 and c is 10 a is 25 and b is 5 and c is 24 a is 100 and b is 5 and c is 5020、可變參數
def total(a=5, *numbers, **phonebook):print('a', a)#遍歷元組中的所有項目for single_item in numbers:print('single_item', single_item)#遍歷字典中的所有項目for first_part, second_part in phonebook.items():print(first_part,second_part)print(total(10,1,2,3,Jack=1123,John=2231,Inge=1560))$ python function_varargs.py a 10 single_item 1 single_item 2 single_item 3 Inge 1560 John 2231 Jack 1123 None21、return 語句
def maximum(x, y):if x > y:return xelif x == y:return 'The numbers are equal'else:return yprint(maximum(2, 3))$ python function_return.py 322、DocStrings
def print_max(x, y):'''Prints the maximum of two numbers.打印兩個數值中的最大數。The two values must be integers.這兩個數都應該是整數'''# 如果可能,將其轉換至整數類型x = int(x)y = int(y)if x > y:print(x, 'is maximum')else:print(y, 'is maximum')print_max(3, 5) print(print_max.__doc__)$ python function_docstring.py 5 is maximum Prints the maximum of two numbers. The two values must be integers.23、模塊
那么如果你想在你所編寫的別的程序中重用一些函數的話,應該怎么辦?正如你可能想象到的那樣,答案是模塊(Modules)。
import sysprint('The command line arguments are:') for i in sys.argv:print(i)print('\n\nThe PYTHONPATH is', sys.path, '\n')$ python module_using_sys.py we are arguments The command line arguments are: module_using_sys.py we are arguments The PYTHONPATH is ['/tmp/py', # many entries here, not shown here '/Library/Python/2.7/site-packages', '/usr/local/lib/python2.7/site-packages']24、from…import 語句
from math import sqrt print("Square root of 16 is", sqrt(16))25、模塊的 name
if __name__ == '__main__':print('This program is being run by itself') else:print('I am being imported from another module')$ python module_using_name.py This program is being run by itself $ python >>> import module_using_name I am being imported from another module >>>26、編寫你自己的模塊
# mymodule.pydef say_hi():print('Hi, this is mymodule speaking.')__version__ = '0.1' # mymodule_demo.pyimport mymodule mymodule.say_hi() print('Version', mymodule.__version__)$ python mymodule_demo.py Hi, this is mymodule speaking. Version 0.1 # mymodule_demo2.pyfrom mymodule import say_hi, __version__ # from mymodule import *say_hi() print('Version', __version__)27、dir 函數
$ python >>> import sys# 給出 sys 模塊中的屬性名稱 >>> dir(sys) ['__displayhook__', '__doc__', 'argv', 'builtin_module_names', 'version', 'version_info'] # only few entries shown here# 給出當前模塊的屬性名稱 >>> dir() ['__builtins__', '__doc__', '__name__', '__package__']# 創建一個新的變量 'a' >>> a = 5>>> dir() ['__builtins__', '__doc__', '__name__', '__package__', 'a']# 刪除或移除一個名稱 >>> del a>>> dir() ['__builtins__', '__doc__', '__name__', '__package__']28、包
包是指一個包含模塊與一個特殊的 init.py 文件的文件夾,后者向 Python 表明這一文
件夾是特別的,因為其包含了 Python 模塊。包是一種能夠方便地分層組織模塊的方式。
29、數據結構
數據結構(Data Structures)基本上人如其名——它們只是一種結構,能夠將一些數據聚合在一起。換句話說,它們是用來存儲一系列相關數據的集合。
Python 中有四種內置的數據結構——列表(List)、元組(Tuple)、字典(Dictionary)和集合(Set)。我們將了解如何使用它們,并利用它們將我們的編程之路變得更加簡單。
30、列表
# This is my shopping list shoplist = ['apple', 'mango', 'carrot', 'banana']print('I have', len(shoplist), 'items to purchase.')print('These items are:', end=' ') for item in shoplist:print(item, end=' ')print('\nI also have to buy rice.') shoplist.append('rice') print('My shopping list is now', shoplist)print('I will sort my list now') shoplist.sort() print('Sorted shopping list is', shoplist)print('The first item I will buy is', shoplist[0]) olditem = shoplist[0] del shoplist[0] print('I bought the', olditem) print('My shopping list is now', shoplist) $ python ds_using_list.py I have 4 items to purchase. These items are: apple mango carrot banana I also have to buy rice. My shopping list is now ['apple', 'mango', 'carrot', 'banana', 'rice'] I will sort my list now Sorted shopping list is ['apple', 'banana', 'carrot', 'mango', 'rice'] The first item I will buy is apple I bought the apple My shopping list is now ['banana', 'carrot', 'mango', 'rice']31、元組
# 我會推薦你總是使用括號 # 來指明元組的開始與結束 # 盡管括號是一個可選選項。 # 明了勝過晦澀,顯式優于隱式。 zoo = ('python', 'elephant', 'penguin') print('Number of animals in the zoo is', len(zoo))new_zoo = 'monkey', 'camel', zoo print('Number of cages in the new zoo is', len(new_zoo)) print('All animals in new zoo are', new_zoo) print('Animals brought from old zoo are', new_zoo[2]) print('Last animal brought from old zoo is', new_zoo[2][2]) print('Number of animals in the new zoo is',len(new_zoo)-1+len(new_zoo[2])) $ python ds_using_tuple.py Number of animals in the zoo is 3 Number of cages in the new zoo is 3All animals in new zoo are ('monkey', 'camel', ('python', 'elephant', 'penguin'))Animals brought from old zoo are ('python', 'elephant', 'penguin') Last animal brought from old zoo is penguin Number of animals in the new zoo is 532、字典
# “ab”是地址(Address)簿(Book)的縮寫ab = {'Swaroop': 'swaroop@swaroopch.com','Larry': 'larry@wall.org','Matsumoto': 'matz@ruby-lang.org','Spammer': 'spammer@hotmail.com' }print("Swaroop's address is", ab['Swaroop'])# 刪除一對鍵值—值配對 del ab['Spammer']print('\nThere are {} contacts in the address-book\n'.format(len(ab)))for name, address in ab.items():print('Contact {} at {}'.format(name, address))# 添加一對鍵值—值配對 ab['Guido'] = 'guido@python.org'if 'Guido' in ab:print("\nGuido's address is", ab['Guido']) $ python ds_using_dict.py Swaroop's address is swaroop@swaroopch.comThere are 3 contacts in the address-bookContact Swaroop at swaroop@swaroopch.com Contact Matsumoto at matz@ruby-lang.org Contact Larry at larry@wall.orgGuido's address is guido@python.org33、序列
shoplist = ['apple', 'mango', 'carrot', 'banana'] name = 'swaroop'# Indexing or 'Subscription' operation # # 索引或“下標(Subcription)”操作符 # print('Item 0 is', shoplist[0]) print('Item 1 is', shoplist[1]) print('Item 2 is', shoplist[2]) print('Item 3 is', shoplist[3]) print('Item -1 is', shoplist[-1]) print('Item -2 is', shoplist[-2]) print('Character 0 is', name[0])# Slicing on a list # print('Item 1 to 3 is', shoplist[1:3]) print('Item 2 to end is', shoplist[2:]) print('Item 1 to -1 is', shoplist[1:-1]) print('Item start to end is', shoplist[:])# 從某一字符串中切片 # print('characters 1 to 3 is', name[1:3]) print('characters 2 to end is', name[2:]) print('characters 1 to -1 is', name[1:-1]) print('characters start to end is', name[:]) $ python ds_seq.py Item 0 is apple Item 1 is mango Item 2 is carrot Item 3 is banana Item -1 is banana Item -2 is carrot Character 0 is s Item 1 to 3 is ['mango', 'carrot'] Item 2 to end is ['carrot', 'banana'] Item 1 to -1 is ['mango', 'carrot'] Item start to end is ['apple', 'mango', 'carrot', 'banana'] characters 1 to 3 is wa characters 2 to end is aroop characters 1 to -1 is waroo characters start to end is swaroop >>> shoplist = ['apple', 'mango', 'carrot', 'banana'] >>> shoplist[::1] ['apple', 'mango', 'carrot', 'banana'] >>> shoplist[::2] ['apple', 'carrot'] >>> shoplist[::3] ['apple', 'banana'] >>> shoplist[::-1] ['banana', 'carrot', 'mango', 'apple']34、集合
>>> bri = set(['brazil', 'russia', 'india']) >>> 'india' in bri True >>> 'usa' in bri False >>> bric = bri.copy() >>> bric.add('china') >>> bric.issuperset(bri) True >>> bri.remove('russia') >>> bri & bric # OR bri.intersection(bric) {'brazil', 'india'}35、引用
print('Simple Assignment') shoplist = ['apple', 'mango', 'carrot', 'banana'] # mylist 只是指向同一對象的另一種名稱 mylist = shoplist# 我購買了第一項項目,所以我將其從列表中刪除 del shoplist[0]print('shoplist is', shoplist) print('mylist is', mylist) # 注意到 shoplist 和 mylist 二者都 # 打印出了其中都沒有 apple 的同樣的列表,以此我們確認 # 它們指向的是同一個對象print('Copy by making a full slice') # 通過生成一份完整的切片制作一份列表的副本 mylist = shoplist[:] # 刪除第一個項目 del mylist[0]print('shoplist is', shoplist) print('mylist is', mylist) # 注意到現在兩份列表已出現不同 $ python ds_reference.py Simple Assignment shoplist is ['mango', 'carrot', 'banana'] mylist is ['mango', 'carrot', 'banana'] Copy by making a full slice shoplist is ['mango', 'carrot', 'banana'] mylist is ['carrot', 'banana']36、有關字符串的更多內容
# 這是一個字符串對象 name = 'Swaroop'if name.startswith('Swa'):print('Yes, the string starts with "Swa"')if 'a' in name:print('Yes, it contains the string "a"')if name.find('war') != -1:print('Yes, it contains the string "war"')delimiter = '_*_' mylist = ['Brazil', 'Russia', 'India', 'China'] print(delimiter.join(mylist)) $ python ds_str_methods.py Yes, the string starts with "Swa" Yes, it contains the string "a" Yes, it contains the string "war" Brazil_*_Russia_*_India_*_China37、問題-實現
我想要一款能為我所有重要的文件創建備份的程序。
- 需要備份的文件與目錄應在一份列表中予以指定。
- 備份必須存儲在一個主備份目錄中。
- 備份文件將打包壓縮成 zip 文件。
- zip 壓縮文件的文件名由當前日期與時間構成。
- 我們使用在任何 GNU/Linux 或 Unix 發行版中都會默認提供的標準 zip 命令進行打包。 在這里你需要了解到只要有命令行界面,你就可以使用任何需要用到的壓縮或歸檔命 令。
38、問題-維護
import os import time# 1. 需要備份的文件與目錄將被 # 指定在一個列表中。 # 例如在 Windows 下: # source = ['"C:\\My Documents"', 'C:\\Code'] # 又例如在 Mac OS X 與 Linux 下: source = ['/Users/swa/notes'] # 在這里要注意到我們必須在字符串中使用雙引號 # 用以括起其中包含空格的名稱。# 2. 備份文件必須存儲在一個 # 主備份目錄中 # 例如在 Windows 下: # target_dir = 'E:\\Backup' # 又例如在 Mac OS X 和 Linux 下: target_dir = '/Users/swa/backup' # 要記得將這里的目錄地址修改至你將使用的路徑# 如果目標目錄不存在則創建目錄 if not os.path.exists(target_dir):os.mkdir(target_dir) # 創建目錄# 3. 備份文件將打包壓縮成 zip 文件。 # 4. 將當前日期作為主備份目錄下的子目錄名稱 today = target_dir + os.sep + time.strftime('%Y%m%d') # 將當前時間作為 zip 文件的文件名 now = time.strftime('%H%M%S')# zip 文件名稱格式 target = today + os.sep + now + '.zip'# 如果子目錄尚不存在則創建一個 if not os.path.exists(today):os.mkdir(today)print('Successfully created directory', today)# 5. 我們使用 zip 命令將文件打包成 zip 格式 zip_command = 'zip -r {0} {1}'.format(target,' '.join(source))# 運行備份 print('Zip command is:') print(zip_command) print('Running:') if os.system(zip_command) == 0:print('Successful backup to', target) else:print('Backup FAILED') $ python backup_ver2.py Successfully created directory /Users/swa/backup/20140329 Zip command is: zip -r /Users/swa/backup/20140329/073201.zip /Users/swa/notes Running: adding: Users/swa/notes/ (stored 0%) adding: Users/swa/notes/blah1.txt (stored 0%) adding: Users/swa/notes/blah2.txt (stored 0%) adding: Users/swa/notes/blah3.txt (stored 0%) Successful backup to /Users/swa/backup/20140329/073201.zip39、問題-產生錯誤
import os import time# 1. 需要備份的文件與目錄將被 # 指定在一個列表中。 # 例如在 Windows 下: # source = ['"C:\\My Documents"', 'C:\\Code'] # 又例如在 Mac OS X 與 Linux 下: source = ['/Users/swa/notes'] # 在這里要注意到我們必須在字符串中使用雙引號 # 用以括起其中包含空格的名稱。# 2. 備份文件必須存儲在一個 # 主備份目錄中 # 例如在 Windows 下: # target_dir = 'E:\\Backup' # 又例如在 Mac OS X 和 Linux 下: target_dir = '/Users/swa/backup' # 要記得將這里的目錄地址修改至你將使用的路徑# 如果目標目錄還不存在,則進行創建 if not os.path.exists(target_dir): os.mkdir(target_dir) # 創建目錄# 3. 備份文件將打包壓縮成 zip 文件。 # 4. 將當前日期作為主備份目錄下的 # 子目錄名稱 today = target_dir + os.sep + time.strftime('%Y%m%d') # 將當前時間作為 zip 文件的文件名 now = time.strftime('%H%M%S')# 添加一條來自用戶的注釋以創建 # zip 文件的文件名 comment = input('Enter a comment --> ') # 檢查是否有評論鍵入 if len(comment) == 0:target = today + os.sep + now + '.zip' else:target = today + os.sep + now + '_' +comment.replace(' ', '_') + '.zip'# 如果子目錄尚不存在則創建一個 if not os.path.exists(today):os.mkdir(today)print('Successfully created directory', today)# 5. 我們使用 zip 命令將文件打包成 zip 格式 zip_command = "zip -r {0} {1}".format(target,' '.join(source))# 運行備份 print('Zip command is:') print(zip_command) print('Running:') if os.system(zip_command) == 0:print('Successful backup to', target) else:print('Backup FAILED') $ python backup_ver3.py File "backup_ver3.py", line 39 target = today + os.sep + now + '_' +^ SyntaxError: invalid syntax40、問題-錯誤修復
import os import time# 1. 需要備份的文件與目錄將被 # 指定在一個列表中。 # 例如在 Windows 下: # source = ['"C:\\My Documents"', 'C:\\Code'] # 又例如在 Mac OS X 與 Linux 下: source = ['/Users/swa/notes'] # 在這里要注意到我們必須在字符串中使用雙引號 # 用以括起其中包含空格的名稱。# 2. 備份文件必須存儲在一個 # 主備份目錄中 # 例如在 Windows 下: # target_dir = 'E:\\Backup' # 又例如在 Mac OS X 和 Linux 下: target_dir = '/Users/swa/backup' # 要記得將這里的目錄地址修改至你將使用的路徑# 如果目標目錄還不存在,則進行創建 if not os.path.exists(target_dir):os.mkdir(target_dir) # 創建目錄# 3. 備份文件將打包壓縮成 zip 文件。 # 4. 將當前日期作為主備份目錄下的 # 子目錄名稱 today = target_dir + os.sep + time.strftime('%Y%m%d') # 將當前時間作為 zip 文件的文件名 now = time.strftime('%H%M%S')# 添加一條來自用戶的注釋以創建 # zip 文件的文件名 comment = input('Enter a comment --> ') # 檢查是否有評論鍵入 if len(comment) == 0:target = today + os.sep + now + '.zip' else:target = today + os.sep + now + '_' + \comment.replace(' ', '_') + '.zip'# 如果子目錄尚不存在則創建一個 if not os.path.exists(today):os.mkdir(today)print('Successfully created directory', today)# 5. 我們使用 zip 命令將文件打包成 zip 格式 zip_command = 'zip -r {0} {1}'.format(target,' '.join(source))# 運行備份 print('Zip command is:') print(zip_command) print('Running:') if os.system(zip_command) == 0:print('Successful backup to', target) else:print('Backup FAILED') $ python backup_ver4.py Enter a comment --> added new examples Zip command is: zip -r /Users/swa/backup/20140329/074122_added_new_examples.zip /Users/swa/notes Running: adding: Users/swa/notes/ (stored 0%) adding: Users/swa/notes/blah1.txt (stored 0%) adding: Users/swa/notes/blah2.txt (stored 0%) adding: Users/swa/notes/blah3.txt (stored 0%) Successful backup to /Users/swa/backup/20140329/074122_added_new_examples.zip41、問題-繼續改進
第四版程序已經是一份對大多數用戶來說都能令人滿意地工作運行的腳本了,不過總會有改進的余地在。例如,你可以在程序中添加 -v 選項來指定程序的顯示信息的詳盡1程度,從而使你的程序可以更具說服力,或者是添加 -q 選項使程序能靜默(Quiet)運行。
另一個可以增強的方向是在命令行中允許額外的文件與目錄傳遞到腳本中。我們可以從sys.argv 列表中獲得這些名稱,然后我們可以通過 list 類提供的 extend 方法把它們添加到我們的 source 列表中.
最重要的改進方向是不使用 os.system 方法來創建歸檔文件,而是使用 zipfile 或 tarfile 內置的模塊來創建它們的歸檔文件。這些都是標準庫的一部分,隨時供你在你的電腦上沒有 zip 程序作為沒有外部依賴的情況下使用這些功能。
不過,在上面的例子中,我一直都在使用 os.system 這種方式作為創建備份的手段,這樣就能保證案例對于所有人來說都足夠簡單同時也確實有用。
你可以試試編寫第五版腳本嗎?在腳本中使用 zipfile 模塊而非 os.system 調用。
42、軟件開發流程
1、What/做什么(分析)
2、How/怎么做(設計)
3、Do It/開始做(執行)
4、Test/測試(測試與修復錯誤)
5、Use/使用(操作或開發)
6、Maintain/維護(改進)
43、面向對象編程(面向高階讀者)
44、self
45、類
46、方法
47、init 方法
48、類變量與對象變量
類變量(Class Variable)是共享的(Shared)——它們可以被屬于該類的所有實例訪問。 該類變量只擁有一個副本,當任何一個對象對類變量作出改變時,發生的變動將在其它所有實例中都會得到體現。
對象變量(Object variable)由類的每一個獨立的對象或實例所擁有。在這種情況下,每個對象都擁有屬于它自己的字段的副本,也就是說,它們不會被共享,也不會以任何方式與其它不同實例中的相同名稱的字段產生關聯。
49、繼承
面向對象編程的一大優點是對代碼的重用(Reuse),重用的一種實現方法就是通過繼承 (Inheritance)機制。繼承最好是想象成在類之間實現類型與子類型(Type and Subtype)關系的工具。
# coding=UTF-8class SchoolMember:'''代表任何學校里的成員。'''def __init__(self, name, age):self.name = nameself.age = ageprint('(Initialized SchoolMember: {})'.format(self.name))def tell(self):'''告訴我有關我的細節。'''print('Name:"{}" Age:"{}"'.format(self.name, self.age), end=" ")class Teacher(SchoolMember):'''代表一位老師。'''def __init__(self, name, age, salary):SchoolMember.__init__(self, name, age)self.salary = salaryprint('(Initialized Teacher: {})'.format(self.name))def tell(self):SchoolMember.tell(self)print('Salary: "{:d}"'.format(self.salary))class Student(SchoolMember):'''代表一位學生。'''def __init__(self, name, age, marks):SchoolMember.__init__(self, name, age)self.marks = marksprint('(Initialized Student: {})'.format(self.name))def tell(self):SchoolMember.tell(self)print('Marks: "{:d}"'.format(self.marks))t = Teacher('Mrs. Shrividya', 40, 30000) s = Student('Swaroop', 25, 75)# 打印一行空白行 print()members = [t, s] for member in members:# 對全體師生工作member.tell() $ python oop_subclass.py (Initialized SchoolMember: Mrs. Shrividya) (Initialized Teacher: Mrs. Shrividya) (Initialized SchoolMember: Swaroop) (Initialized Student: Swaroop)Name:"Mrs. Shrividya" Age:"40" Salary: "30000" Name:"Swaroop" Age:"25" Marks: "75"50、輸入與輸出
def reverse(text):return text[::-1]def is_palindrome(text):return text == reverse(text)something = input("Enter text: ") if is_palindrome(something):print("Yes, it is a palindrome") else:print("No, it is not a palindrome")$ python3 io_input.py Enter text: sir No, it is not a palindrome $ python3 io_input.py Enter text: madam Yes, it is a palindrome $ python3 io_input.py Enter text: racecar Yes, it is a palindrome51、文件
你可以通過創建一個屬于 file 類的對象并適當使用它的 read 、 readline 、 write 方法來打開或使用文件,并對它們進行讀取或寫入。讀取或寫入文件的能力取決于你指定以何種方式打開文件。最后,當你完成了文件,你可以調用 close 方法來告訴 Python 我們已經完成了對該文件的使用。
poem = '''\ Programming is fun When the work is done if you wanna make your work also fun: use Python! '''# 打開文件以編輯('w'riting) f = open('poem.txt', 'w') # 向文件中編寫文本 f.write(poem) # 關閉文件 f.close()# 如果沒有特別指定, # 將假定啟用默認的閱讀('r'ead)模式 f = open('poem.txt') while True:line = f.readline()# 零長度指示 EOFif len(line) == 0:break# 每行(`line`)的末尾# 都已經有了換行符#因為它是從一個文件中進行讀取的print(line, end='') # 關閉文件 f.close() $ python3 io_using_file.py Programming is fun When the work is done if you wanna make your work also fun: use Python!52、Pickle
Python 提供了一個叫作 Pickle 的標準模塊,通過它你可以將任何純 Python 對象存儲到一個文件中,并在稍后將其取回。這叫作持久地(Persistently)存儲對象。
import pickle# The name of the file where we will store the object shoplistfile = 'shoplist.data' # The list of things to buy shoplist = ['apple', 'mango', 'carrot']# Write to the file f = open(shoplistfile, 'wb') # Dump the object to a file pickle.dump(shoplist, f) f.close()# Destroy the shoplist variable del shoplist# Read back from the storage f = open(shoplistfile, 'rb') # Load the object from the file storedlist = pickle.load(f) print(storedlist)$ python io_pickle.py ['apple', 'mango', 'carrot']要想將一個對象存儲到一個文件中,我們首先需要通過 open 以寫入(write)二進制 (binary)模式打開文件,然后調用 pickle 模塊的 dump 函數。這一過程被稱作封裝 (Pickling)。 接著,我們通過 pickle 模塊的 load 函數接收返回的對象。這個過程被稱作拆封(Unpickling)。
53、Unicode
# encoding=utf-8 import iof = io.open("abc.txt", "wt", encoding="utf-8") f.write(u"Imagine non-English language here") f.close()text = io.open("abc.txt", encoding="utf-8").read() print(text)54、錯誤異常
>>> Print("Hello World") Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'Print' is not defined >>> print("Hello World") Hello World >>> s = input('Enter something --> ') Enter something --> Traceback (most recent call last): File "<stdin>", line 1, in <module> EOFError55、處理異常
try:text = input('Enter something --> ') except EOFError:print('Why did you do an EOF on me?') except KeyboardInterrupt:print('You cancelled the operation.') else:print('You entered {}'.format(text)) # Press ctrl + d $ python exceptions_handle.py Enter something --> Why did you do an EOF on me?# Press ctrl + c $ python exceptions_handle.py Enter something --> ^CYou cancelled the operation.$ python exceptions_handle.py Enter something --> No exceptions You entered No exceptions56、拋出異常
你可以通過 raise 語句來引發一次異常,具體方法是提供錯誤名或異常名以及要拋出 (Thrown)異常的對象。 你能夠引發的錯誤或異常必須是直接或間接從屬于 Exception (異常) 類的派生類。
# encoding=UTF-8 class ShortInputException(Exception):'''一個由用戶定義的異常類'''def __init__(self, length, atleast):Exception.__init__(self)self.length = lengthself.atleast = atleasttry:text = input('Enter something --> ')if len(text) < 3:raise ShortInputException(len(text), 3)# 其他工作能在此處繼續正常運行 except EOFError:print('Why did you do an EOF on me?') except ShortInputException as ex:print(('ShortInputException: The input was ' +'{0} long, expected at least {1}').format(ex.length, ex.atleast)) else:print('No exception was raised.') $ python exceptions_raise.py Enter something --> a ShortInputException: The input was 1 long, expected at least 3$ python exceptions_raise.py Enter something --> abc No exception was raised.57、Try … Finally
import sys import timef = None try:f = open("poem.txt")# 我們常用的文件閱讀風格while True:line = f.readline()if len(line) == 0:breakprint(line, end='')sys.stdout.flush()print("Press ctrl+c now")# 為了確保它能運行一段時間time.sleep(2)except IOError:print("Could not find file poem.txt") except KeyboardInterrupt:print("!! You cancelled the reading from the file.") finally:if f:f.close()print("(Cleaning up: Closed the file)") $ python exceptions_finally.py Programming is fun Press ctrl+c now ^C!! You cancelled the reading from the file. (Cleaning up: Closed the file)58、with 語句
59、sys 模塊
60、日志模塊
如果你想將一些調試(Debugging)信息或一些重要的信息儲存在某個地方,以便你可以檢查你的程序是否如你所期望那般運行,應該怎么做?你應該如何將這些信息“儲存在某個地方”?這可以通過 logging 模塊來實現。
import os import platform import loggingif platform.platform().startswith('Windows'):logging_file = os.path.join(os.getenv('HOMEDRIVE'),os.getenv('HOMEPATH'),'test.log') else:logging_file = os.path.join(os.getenv('HOME'),'test.log')print("Logging to", logging_file)logging.basicConfig(level=logging.DEBUG,format='%(asctime)s : %(levelname)s : %(message)s',filename=logging_file,filemode='w', )logging.debug("Start of the program") logging.info("Doing something") logging.warning("Dying now") $ python stdlib_logging.py Logging to /Users/swa/test.log$ cat /Users/swa/test.log 2014-03-29 09:27:36,660 : DEBUG : Start of the program 2014-03-29 09:27:36,660 : INFO : Doing something 2014-03-29 09:27:36,660 : WARNING : Dying now61、更多-傳遞元組
62、更多-特殊方法
63、更多-單語句塊
64、更多-Lambda 表格
65、更多-列表推導
66、更多-在函數中接收元組與字典
67、更多-assert 語句
68、更多-裝飾器
裝飾器(Decorators)是應用包裝函數的快捷方式。這有助于將某一功能與一些代碼一遍又一遍地“包裝”。舉個例子,我為自己創建了一個 retry 裝飾器,這樣我可以將其運用到任何函數之中,如果在一次運行中拋出了任何錯誤,它就會嘗試重新運行,直到最大次數 5 次,并且每次運行期間都會有一定的延遲。這對于你在對一臺遠程計算機進行網絡調用的情況十分有用。
from time import sleep from functools import wraps import logging logging.basicConfig() log = logging.getLogger("retry")def retry(f):@wraps(f)def wrapped_f(*args, **kwargs):MAX_ATTEMPTS = 5for attempt in range(1, MAX_ATTEMPTS + 1):try:return f(*args, **kwargs)except:log.exception("Attempt %s/%s failed : %s",attempt,MAX_ATTEMPTS,(args, kwargs))sleep(10 * attempt)log.critical("All %s attempts failed : %s",MAX_ATTEMPTS,(args, kwargs))return wrapped_fcounter = 0@retry def save_to_database(arg):print("Write to a database or make a network call or etc.")print("This will be automatically retried if exception is thrown.")global countercounter += 1# 這將在第一次調用時拋出異常# 在第二次運行時將正常工作(也就是重試)if counter < 2:raise ValueError(arg)if __name__ == '__main__':save_to_database("Some bad value") $ python more_decorator.py Write to a database or make a network call or etc. This will be automatically retried if exception is thrown. ERROR:retry:Attempt 1/5 failed : (('Some bad value',), {}) Traceback (most recent call last):File "more_decorator.py", line 14, in wrapped_freturn f(*args, **kwargs)File "more_decorator.py", line 39, in save_to_databaseraise ValueError(arg) ValueError: Some bad value Write to a database or make a network call or etc. This will be automatically retried if exception is thrown.69、邁出下一步
1、編寫一款你自己的命令行地址簿程序,你可以用它瀏覽、添加、編輯、刪除或搜索你的 聯系人,例如你的朋友、家人、同事,還有他們諸如郵件地址、電話號碼等多種信息。 這些詳細信息必須被妥善儲存以備稍后的檢索。
2、創建一個網站,學習使用 Flask 來創建你自己的網站。
3、假設你希望使用 Python 來創建你自己的圖形程序。這可以通過采用一個 GUI(Graphical User Interface,圖形用戶界面)庫和它們的 Python 綁定來實現。綁定是允許你用 Python 編寫你自己的程序,然后使用它們在 C 或 C++ 或其它語言寫編寫的庫。
70、總結
現在我們已經行至本書末尾,不過,正如人們所說,這是昭示著開始的終結!你現在已經是一名狂熱 Python 用戶,毫無疑問,你已準備好通過 Python 來解決諸多問題了。你可以開始自動化你的電腦,去做任何你以前難以想象的事情,你可以開始編寫你自己的游戲,開始做更多更多的事,遠不僅此。來,讓我們出發吧!
總結
以上是生活随笔為你收集整理的简明 Python 教程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: secureCRT中文字符乱码
- 下一篇: python 编程模型