《Python編程:從入門到實踐》2-9章 筆記

2 變量和簡單數據類型

2.2 變量

2.2.1 變量的命名和使用

牢記有關變量的規則php

  • 變量名只能包含字母、數字和下劃線,變量名能夠以字母下劃線開頭,但不能以數字開頭。錯誤示例:1_message。
  • 變量名不能包含空格,但可以使用下劃線來分隔其中單詞。錯誤示例:greeting message 。正確示例:greeting_message
  • 不要將Python關鍵字和函數名用做變量名
  • 變量名應既簡短又具描述性。例如:name 比 n 好,student_name比 s_n 好,name_length比 length_of_persons_name 好。
  • 慎用小寫字母l和大寫字母O,它們可能被人錯當作數字1和0。

2.2.2 使用變量時避免明顯錯誤

traceback是一條記錄,指出瞭解釋器嘗試運行代碼時,在什麼地方陷入了困境。
要理解新的編程概念,最佳的方式是嘗試在程序中使用它們。java

2.3 字符串

2.3.1 使用方法修改字符串的大小寫

代碼:python

name = "ada lovelace"
print name.title()
print name.upper()
print name.lower()

輸出結果:程序員

Ada Lovelace
ADA LOVELACE
ada lovelace

2.3.4 刪除空白

str.rstrip([chars])     # 剔除字符串結尾的指定字符(默認爲空白)
lstrip([chars])     # 剔除字符串開頭的指定字符(默認爲空白)
strip([chars])      # 同時剔除字符串開頭和結尾的指定字符(默認爲空白)

2.3.6 Python 2中的print語句

在Python 2中,無需將打印的內容放在括號內。
從技術上說,Python 3中的print是一個函數,所以括號必不可少。sql

2.4 數字

2.4.4 Python 2中的整數

Python 2中,整數除法的結果只包含整數部分,小數部分被刪除,注意不是四捨五入,而是直接刪除小數部分。
Python 2中,要避免這種狀況,務必確保至少有一個操做爲浮點數,這樣結果也將爲浮點數。編程

2.5 註釋

2.5.2 該編寫什麼樣的註釋

當前,大多數軟件都是合做編寫的,編寫者多是同一家公司的多名員工,也多是衆多致力於同一個開源項目的人員。訓練有素的程序員都但願代碼中包含註釋,所以最好從如今開始就在程序中添加描述性註釋。做爲新手,最值得養成的習慣之一是,在代碼中編寫清晰、簡潔的註釋。
若是不肯定是否要編寫註釋,就問問本身,找到合理的解決方案前,是否考慮了多個解決方案。若是答案是確定的,就編寫註釋對的解決方案進行說明吧。相比回過頭去再添加註釋,刪除多餘的註釋要容易得多。json

2.6 Python之禪

在解釋器中執行命令import this就會顯示Tim Peters的The Zen of python:ruby

>>>import this
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

3 列表簡介

3.2.1 修改列表元素

motorcycles = ['honda', 'yamaha', 'suzuki']
print (motorcycles)
motorcycles[0] = 'ducati'
print (motorcycles)

輸出:bash

['honda', 'yamaha', 'suzuki']
['ducati', 'yamaha', 'suzuki']

3.2.2 在列表中添加元素

  • 在列表末尾添加元素
motorcycles = ['honda', 'yamaha', 'suzuki']
print(motorcycles)

motorcycles.append('ducati')
print(motorcycles)

輸出:markdown

['honda', 'yamaha', 'suzuki']
['honda', 'yamaha', 'suzuki', 'ducati']
  • 在列表中插入元素
    使用方法insert()能夠在列表的任何位置添加新元素。須要制定新元素的索引和值。
motorcycles = ['honda', 'yamaha', 'suzuki']
motorcycles.insert(0, 'ducati')
print(motorcycles)

這種操做將列表既有的每一個元素都右移一個位置:

['ducati', 'honda', 'yamaha', 'suzuki']

3.2.3 從列表中刪除元素

能夠根據位置來刪除列表中的元素。

  • 使用del語句刪除元素
motorcycles = ['honda', 'yamaha', 'suzuki']
print(motorcycles)

del motorcycles[0]
print(motorcycles)

輸出:

['honda', 'yamaha', 'suzuki']
['yamaha', 'suzuki']
  • 使用方法pop()刪除元素
    方法pop()可刪除列表末尾的元素,並可以接着使用它。
motorcycles = ['honda', 'yamaha', 'suzuki']
print(motorcycles)
popped_motorcycle = motorcycles.pop()
print(motorcycles)
print(popped_motorcycle)

輸出:

['honda', 'yamaha', 'suzuki']
['honda', 'yamaha']
suzuki
  • 彈出列表中任何位置處的元素
    可使用pop()方法來刪除列表中任何位置的元素,只需在括號中指定要刪除的元素的索引便可。
motorcycles = ['honda', 'yamaha', 'suzuki']
first_owned = motorcycles.pop(0)
print('The first motorcycle I owned was a ' + first_owned.title() + '.')

輸出:

The first motorcycle I owned was a Honda.
  • 根據值刪除元素
    可以使用方法remove()
motorcycles = ['honda', 'yamaha', 'suzuki', 'ducati']
print(motorcycles)

motorcycles.remove('ducati')
print(motorcycles)

輸出:

['honda', 'yamaha', 'suzuki', 'ducati']
['honda', 'yamaha', 'suzuki']

使用remove()從列表中刪除元素時,也可接着使用它的值

motorcycles = ['honda', 'yamaha', 'suzuki', 'ducati']
too_expensive = 'ducati'
motorcycles.remove(too_expensive)
print(motorcycles)

值’ducati’已經從列表中刪除,但它還存儲在變量too_expensive

['honda', 'yamaha', 'suzuki', 'ducati']
['honda', 'yamaha', 'suzuki']
A Ducati is too expensive for me.

方法remove()只刪除第一個指定的值。若是要刪除的值可能在列表中出現屢次,就須要使用循環來判斷是否刪除了全部這樣的值。

3.3.1 使用方法sort()對列表進行永久性排序

cars = ['bmw', 'audi', 'toyota', 'subaru']
cars.sort()
print(cars)

永久性排序:

['audi', 'bmw', 'subaru', 'toyota']

能夠按與字母順序相反的順序排列列表元素,爲此,只需向sort()方法傳遞參數reverse=True

cars = ['bmw', 'audi', 'toyota', 'subaru']
cars.sort(reverse=True)
print(cars)

一樣是永久性修改列表元素順序:

['toyota', 'subaru', 'bmw', 'audi']

3.3.2 使用函數sorted()對列表進行臨時排序

cars = ['bmw', 'audi', 'toyota', 'subaru']
print("Here is the original list:")
print(cars)

print("\nHere is the sorted list:")
print(sorted(cars))

print("\nHere is the original list again:")
print(cars)

輸出:

Here is the original list:
['bmw', 'audi', 'toyota', 'subaru']
Here is the sorted list:
['audi', 'bmw', 'subaru', 'toyota']
Here is the original list again:
['bmw', 'audi', 'toyota', 'subaru']

若是要按與字母順序相反的順序顯示列表,也可向函數sorted() 傳遞參數reverse=True

注意 在並不是全部的值都是小寫時,按字母順序排列列表要複雜些。決定排列順序時,有多種解讀大寫字母的方式,要指定準確的排列順序,可能比咱們這裏所作的要複雜。

3.3.3 倒着打印列表

要反轉列表元素的排列順序,可以使用方法reverse()

cars = ['bmw', 'audi', 'toyota', 'subaru']
print(cars)

cars.reverse()
print(cars)

注意,reverse()不是指按與字母順序相反的順序排列列表元素,而只是反轉列表元素的排列順序:

['bmw', 'audi', 'toyota', 'subaru']
['subaru', 'toyota', 'audi', 'bmw']

方法reverse()永久性地修改列表元素的排列順序,但可隨時恢復到原來的排列順序,爲此只需對列表再次調用reverse() 便可。

3.4 使用列表時避免索引錯誤

假設有一個包含三個元素的列表,卻要求獲取第四個元素:

motorcycles = ['honda', 'yamaha', 'suzuki']
print(motorcycles[3])

這將致使索引錯誤 :

Traceback (most recent call last): File "motorcycles.py", line 3, in <module> print(motorcycles[3]) IndexError: list index out of range

索引錯誤意味着Python沒法理解指定的索引。程序發生索引錯誤時,請嘗試將指定的索引減1,而後再次運行程序,看看結果是否正確。

每當須要訪問最後一個列表元素時,均可使用索引-1 。這在任何狀況下都行之有效,即使最後一次訪問列表後,其長度發生了變化。

4 操做列表

4.3 建立數值列表

4.3.1 使用函數range()

for value in range(1, 6):
    print(value)

注意輸出不包含第二個值:

1
2
3
4
5

函數range()還可指定步長
語法:

range(start, stop[, step])

輸入:

even_numbers = list(range(2,11,2))
print(even_numbers)

輸出:

[2, 4, 6, 8, 10]

4.3.3 對數字列表執行簡單的統計計算

min() max() sum()

4.3.4 列表解析

列表解析將for循環和建立新元素的代碼合併成一行,並自動附加新元素。

squares = [value**2 for value in range(1,11)]
print(squares)

輸出:

[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

等同於:

squares = []
for value in range(1, 11):
    squares.append(value**2)
print(squares)

4.4.3 複製列表

要複製列表,可建立一個包含整個列表的切片,方法是同時省略起始索引和終止索引([:])。
咱們在不指定任何索引的狀況下從列表my_foods中提取一個切片,從而建立了這個列表的副本,再將該副本存儲到變量friend_foods中。
覈實咱們確實有兩個列表:

my_foods = ['pizza', 'falafel', 'carrot cake']
friend_foods = my_foods[:]

my_foods.append('cannoli')
friend_foods.append('ice cream')

print("My favorite foods are:")
print(my_foods)
print("\nMy friend's favorite foods are:")
print(friend_foods)

輸出:

My favorite foods are:
['pizza', 'falafel', 'carrot cake', 'cannoli']
My friend's favorite foods are:
['pizza', 'falafel', 'carrot cake', 'ice cream']

假若咱們只是簡單地將my_foods 賦給friend_foods就不能獲得兩個列表。

4.5 元組

列表很是適合用於存儲在程序運行期間可能變化的數據集。
列表是能夠修改的,這對處理網站的用戶列表或遊戲中的角色列表相當重要。然而,有時候須要建立一系列不可修改的元素,元組能夠知足這種需求。
Python將不能修改的值稱爲不可變的 ,而不可變的列表被稱爲元組

4.5.1 定義元組

元組看起來猶如列表,但使用圓括號而不是方括號來標識。

dimensions = (200, 50)
dimensions[0] = 250

輸出:

Traceback (most recent call last): File "dimensions.py", line 3, in <module> dimensions[0] = 250 TypeError: 'tuple' object does not support item assignment

代碼試圖修改第一個元素的值,致使Python返回類型錯誤消息。因爲試圖修改元組的操做是被禁止的,所以Python指出不能給元組的元素賦值。

4.5.2 遍歷元組中的全部值

可以使用for循環來遍歷元組中的全部值。
相比於列表,元組是更簡單的數據結構。若是須要存儲的一組值在程序的整個生命週期內都不變,可以使用元組。

4.6 設置代碼格式

4.6.1 格式設置指南

PEP 8是最古老的PEP(Python Enhancement Proposal,PEP)之一,它向Python程序員提供了代碼格式設置指南。PEP 8的篇幅很長,但大都與複雜的編碼結構相關。
若是必定要在讓代碼易於編寫和易於閱讀之間作出選擇,Python程序員幾乎老是會選擇後者。

4.6.3 行長

不少Python程序員都建議每行不超過80字符。
PEP 8還建議註釋的行長都不超過72字符,由於有些工具爲大型項目自動生成文檔時,會在每行註釋開頭添加格式化字符。

PEP 8中有關行長的指南並不是不可逾越的紅線,有些小組將最大行長設置爲99字符。在學習期間,不用過多地考慮代碼的行長,但別忘了,協做編寫程序時,你們幾乎都遵照PEP 8指南。在大多數編輯器中,均可設置一個視覺標誌——一般是一條豎線,讓你知道不能越過的界線在什麼地方。

5 if語句

5.3.2 if-else 語句

else 語句指定了條件測試未經過時要執行的操做。

5.3.3 if-elif-else 結構

常常須要檢查超過兩個的情形,爲此可以使用Python提供的if-elif-else結構。
Python只執行if-elif-else結構中的一個代碼塊,它依次檢查每一個條件測試,直到遇到經過了的條件測試。

age = 12
if age < 4:
    print("Your admission cost is $0.")
elif age < 18:
    print("Your admission cost is $5.")
else:
    print("Your admission cost is $10.")

5.3.4 使用多個elif 代碼塊

可根據須要使用任意數量的elif代碼塊:

age = 12
if age < 4:
    price = 0
elif age < 18:
    price = 5
elif age < 65:
    price = 10
else:
    price = 5

print("Your admission cost is $" + str(price) + ".")

5.3.5 省略else 代碼塊

Python並不要求if-elif 結構後面必須有else 代碼塊。在有些狀況下,else 代碼塊頗有用;而在其餘一些狀況下,使用一條elif 語句來處理特定的情形更清晰。

age = 12
if age < 4:
    price = 0
elif age < 18:
    price = 5
elif age < 65:
    price = 10
elif age >= 65:
    price = 5
print("Your admission cost is $" + str(price) + ".")

else 是一條一應俱全的語句,只要不知足任何if 或elif 中的條件測試,其中的代碼就會執行,這可能會引入無效甚至惡意的數據。若是知道最終要測試的條件,應考慮使用一個elif 代碼塊來代替else 代碼塊。這樣就能夠確定,僅當知足相應的條件時,代碼纔會執行。

6 字典

可將任何Python對象用做字典中的值。

6.2.2 添加鍵-值對

字典是一種動態結構,可隨時在其中添加鍵-值對。要添加鍵-值對,可依次指定字典名、用方括號括起的鍵和相關聯的值。

alien_0 = {'color': 'green', 'points': 5}
print(alien_0)
alien_0['x_position'] = 0
alien_0['y_position'] = 25
print(alien_0)

輸出:

{'color': 'green', 'points': 5}
{'color': 'green', 'points': 5, 'x_position': 0, 'y_position': 25}

6.2.3 先建立一個空字典

使用字典來存儲用戶提供的數據或在編寫能自動生成大量鍵-值對的代碼時,一般都須要先定義一個空字典。

6.2.4 修改字典中的值

alien_0 = {'color': 'green'}
print("The alien is " + alien_0['color'] + ".")
alien_0['color'] = 'yellow'   # 修改值
print("The alien is now " + alien_0['color'] + ".")

輸出:

The alien is green.
The alien is now yellow.

6.2.5 刪除鍵-值對

可以使用del 語句將相應的鍵-值對完全刪除,使用del 語句時,必須指定字典名和要刪除的鍵。

alien_0 = {'color': 'green', 'points': 5}
print(alien_0)
del alien_0['points']
print(alien_0)

輸出:

{'color': 'green', 'points': 5}
{'color': 'green'}

6.2.6 由相似對象組成的字典

肯定須要使用多行來定義字典時,在輸入左花括號後按回車鍵,再在下一行縮進四個空格,指定第一個鍵-值對,並在它後面加上一個逗號。此後再次按回車鍵時,文本編輯器將自動縮進後續鍵-值對,且縮進量與第一個鍵-值對相同。
定義好字典後,在最後一個鍵-值對的下一行添加一個右花括號,並縮進四個空格,使其與字典中的鍵對齊。另一種不錯的作法是在最後一個鍵-值對後面也加上逗號,爲之後在下一行添加鍵-值對作好準備。

favorite_languages = {
    'jen': 'python',
    'sarah': 'c',
    'edward': 'ruby',
    'phil': 'python',
    }

6.3 遍歷字典

6.3.1 遍歷全部的鍵-值對

user_0 = {
    'username': 'efermi',
    'first': 'enrico',
    'last': 'fermi',
    }
for key, value in user_0.items():  # for語句的第二部分包含字典名和方法items()
    print("\nKey: " + key)
    print("Value: " + value)

輸出:

Key: last
Value: fermi

Key: first Value: enrico Key: username Value: efermi

經過「+」鏈接符鏈接keyvalue

favorite_languages = {
    'jen': 'python',
    'sarah': 'c',
    'edward': 'ruby'
    'phil': 'python',
    }

for name, language in favorite_languages.items():
    print(name.title() + "'s favorite language is " + language.title() + ".")

輸出:

Jen's favorite language is Python.

Sarah's favorite language is C.

Phil's favorite language is Python.

Edward's favorite language is Ruby.

6.3.2 遍歷字典中的全部

在不須要使用字典中的值時,方法keys() 頗有用。

favorite_languages = {
    'jen': 'python',
    'sarah': 'c',
    'edward': 'ruby',
    'phil': 'python',
    }

for name in favorite_languages.keys():
    print(name.title())

輸出:

Jen
Sarah
Phil
Edward

遍歷字典時,會默認遍歷全部的鍵,所以,若是將上述代碼中的for name in favorite_languages.keys():替換爲 for name in favorite_languages:,輸出將不變。

若是顯式地使用方法keys()可以讓代碼更容易理解,你能夠選擇這樣作,但若是你願意,也可省略它。

favorite_languages = {
    'jen': 'python',
    'edward': 'ruby',
    'phil': 'python',
    }

friends = ['phil', 'sarah']
for name in favorite_languages.keys():
    print(name.title())
    if name in friends:
        print("Hi " + name.title() + ", I see your favorite language is " + favorite_languages[name].title() + "!")

輸出:

Edward
Jen
Phil
Hi Phil, I see your favorite language is Python!

7 用戶輸入和while循環

7.1 函數input()

函數input()接受一個參數:即要向用戶顯示的提示 或說明,讓用戶知道該如何作。

7.1.1 編寫清晰的程序

個性化打招呼:

name = input("Please enter your name: ")
print("Hello, " + name + "!")

7.1.2 使用int() 來獲取數值輸入

height = input("How tall are you, in inches? ")
height = int(height)
if height >= 36:
    print("\nYou're tall enough to ride!")
else:
    print("\nYou'll be able to ride when you're a little older.")

輸出:

How tall are you, in inches? 71
You're tall enough to ride!

將數值輸入用於計算和比較前,務必將其轉換爲數值表示。

7.1.4 在Python 2.7中獲取輸入

若是使用的是Python 2.7,應使用函數raw_input()來提示用戶輸入。這個函數與Python 3中的input()同樣,也將輸入解讀爲字符串。
Python 2.7也包含函數input(),但它將用戶輸入解讀爲Python代碼,並嘗試運行它們。所以,最好的結果是出現錯誤,指出Python不明白輸入的代碼;而最糟的結果是,將運行本來無心運行的代碼。

7.2.2 讓用戶選擇什麼時候退出

咱們在其中定義了一個退出值,只要用戶輸入的不是這個值,程序就接着運行:

Tell me something, and I will repeat it back to you:
Enter 'quit' to end the program. Hello everyone!
Hello everyone!
Tell me something, and I will repeat it back to you:
Enter 'quit' to end the program. Hello again.
Hello again.
Tell me something, and I will repeat it back to you:
Enter 'quit' to end the program. quit

代碼:

prompt = "\nTell me something, and I will repeat it back to you:"
prompt += "\nEnter 'quit' to end the program. "
message = ""
while message != 'quit':
    message = raw_input(prompt)  # 注意raw_input()已包含print(prompt)步驟
    #print(message)
if message == 'quit':
    print(message)

7.2.3 使用標誌

在要求不少條件都知足才繼續運行的程序中,可定義一個變量,用於判斷整個程序是否處於活動狀態。這個變量被稱爲標誌,充當了程序的交通訊號燈。可以讓程序在標誌爲True時繼續運行,並在任何事件致使標誌的值爲False時讓程序中止運行。這樣,在while語句中就只需檢查一個條件——標誌的當前值是否爲True,並將全部測試(是否發生了應將標誌設置爲False的事件)都放在其餘地方,從而讓程序變得更爲整潔。

prompt = "\nTell me something, and I will repeat it back to you:"
prompt += "\nEnter 'quit' to end the program. "

active = True
while active:
    message = input(prompt)
    if message == 'quit':
        active = False
    else:
        print(message)

7.2.4 使用break退出循環

要當即退出while循環,再也不運行循環中餘下的代碼,也無論條件測試的結果如何,可以使用break語句。
注意: 在任何Python循環中均可使用break語句。例如,可以使用break語句來退出遍歷列表或字典的for循環。

7.2.5 在循環中使用 continue

要返回到循環開頭,並根據條件測試結果決定是否繼續執行循環,可以使用continue語句,它不像break語句那樣再也不執行餘下的代碼並退出整個循環。
例如,來看一個從1數到10,但只打印其中偶數的循環:

current_number = 0 
while current_number < 10: 
    current_number += 1 
    if current_number % 2 == 0: 
        continue  #忽略餘下的代碼,並返回到循環的開頭

    print(current_number)

輸出:

1
3
5
7
9

7.2.6 避免無限循環

每一個while循環都必須有中止運行的途徑,這樣纔不會沒完沒了地執行下去。

要避免編寫無限循環,務必對每一個while循環進行測試,確保它按預期那樣結束。若是但願程序在用戶輸入特定值時結束,可運行程序並輸入這樣的值;若是在這種狀況下程序沒有結束,請檢查程序處理這個值的方式,確認程序至少有一個這樣的地方能讓循環條件爲False或讓break語句得以執行。

7.3 使用 while 循環來處理列表和字典

for循環是一種遍歷列表的有效方式,但在for循環中不該修改列表,不然將致使Python難以跟蹤其中的元素。
要在遍歷列表的同時對其進行修改,可以使用while循環。經過將while循環同列表和字典結合起來使用,可收集、存儲並組織大量輸入,供之後查看和顯示。

7.3.2 刪除包含特定值的全部列表元素

假設有一個寵物列表,其中包含多個值爲’cat’的元素。要刪除全部這些元素,可不斷運行一個while循環,直到列表中再也不包含值’cat’,以下所示:

pets = ['dog', 'cat', 'dog', 'goldfish', 'cat', 'rabbit', 'cat'] 
print(pets) 

while 'cat' in pets: 
    pets.remove('cat')    #list.remove(obj)移除列表中某個值的第一個匹配項
print(pets)

輸出:

['dog', 'cat', 'dog', 'goldfish', 'cat', 'rabbit', 'cat']
['dog', 'dog', 'goldfish', 'rabbit']

7.3.3 使用用戶輸入來填充字典

建立一個調查程序,其中的循環每次執行時都提示輸入被調查者的名字和回答。咱們將收集的數據存儲在一個字典中,以便將回答同被調查者關聯起來:
注意python2 中用raw_input(),python3 中input()

responses = {} 

# 設置一個標誌,指出調查是否繼續 
polling_active = True 

while polling_active: 
    # 提示輸入被調查者的名字和回答
    name = raw_input("\nWhat is your name? ") 
    response = raw_input("Which mountain would you like to climb someday? ") 

    # 將答卷存儲在字典中 
    responses[name] = response 

    # 看看是否還有人要參與調查 
    repeat = raw_input("Would you like to let another person respond? (yes/ no) ") 
    if repeat == 'no': 
        polling_active = False 

# 調查結束,顯示結果 
print("\n--- Poll Results ---") 
for name, response in responses.items(): 
    print(name + " would like to climb " + response + ".")

輸出:

What is your name? Eric  
Which mountain would you like to climb someday? Denali  
Would you like to let another person respond? (yes/ no) yes  

What is your name? Lynn  
Which mountain would you like to climb someday? Devil's Thumb 
Would you like to let another person respond? (yes/ no) no  

--- Poll Results ---  
Lynn would like to climb Devil's Thumb. 
Eric would like to climb Denali.

8 函數

8.5.2 使用任意數量的關鍵字實參

有時候,須要接受任意數量的實參,但預先不知道傳遞給函數的會是什麼樣的信息。在這種狀況下,可將函數編寫成可以接受任意數量的鍵-值對——調用語句提供了多少就接受多少。

def build_profile(first, last, **user_info): 
    """建立一個字典,其中包含咱們知道的有關用戶的一切""" 
    profile = {} 
    profile['first_name'] = first 
    profile['last_name'] = last 
    for key, value in user_info.items(): 
        profile[key] = value 
    return profile 

user_profile = build_profile('albert', 'einstein', 
                             location='princeton', 
                             field='physics') 
print(user_profile)

輸出:

{'field': 'physics', 'first_name': 'albert', 'last_name': 'einstein', 'location': 'princeton'}

形參**user_info中的兩個星號讓Python建立一個名爲user_info的空字典,並將收到的全部名稱-值對都封裝到這個字典中。在這個函數中,能夠像訪問其餘字典那樣訪問user_info中的名稱—值對。
在這裏,返回的字典包含用戶的名和姓,還有求學的地方和所學專業。編寫函數時,能夠以各類方式混合使用位置實參、關鍵字實參和任意數量的實參。

8.6 將函數存儲在模塊中

將函數存儲在被稱爲模塊的獨立文件中,再將模塊導入到主程序中,import語句容許在當前運行的程序文件中使用模塊中的代碼。
經過將函數存儲在獨立的文件中,可隱藏程序代碼的細節,將重點放在程序的高層邏輯上。
這還能讓你在衆多不一樣的程序中重用函數。將函數存儲在獨立文件中後,可與其餘程序員共享這些文件而不是整個程序。
知道如何導入函數還能讓你使用其餘程序員編寫的函數庫。

8.6.1 導入整個模塊

import module_name

若是使用import語句導入了名爲module_name.py的整個模塊,就可以使用下面的語法來使用其中任何一個函數:

module_name.function_name()

8.6.2 導入特定的函數

from module_name import function_name

經過用逗號分隔函數名,可根據須要從模塊中導入任意數量的函數:

from module_name import function_0, function_1, function_2

若使用這種語法,調用函數時就無需使用句點。因爲在import語句中顯式地導入了函數function_name(),所以調用它時只需指定其名稱。

8.6.3 使用 as 給函數指定別名

若是要導入的函數的名稱可能與程序中現有的名稱衝突,或者函數的名稱太長,可指定簡短而獨一無二的別名——函數的另外一個名稱,相似於外號。要給函數指定這種特殊外號,須要在導入它時這樣作。
下面給函數make_pizza()指定了別名mp()。這是在import語句中使用make_pizza as mp實現的,關鍵字as將函數重命名爲你提供的別名:

from pizza import make_pizza as mp 

mp(16, 'pepperoni') 
mp(12, 'mushrooms', 'green peppers', 'extra cheese')

上面的import語句將函數make_pizza()重命名爲mp();在這個程序中,每當須要調用make_pizza()時,均可簡寫成mp(),而Python將運行make_pizza()中的代碼,這可避免與這個程序可能包含的函數make_pizza()混淆。
指定別名的通用語法以下:

from module_name import function_name as fn

8.6.4 使用 as 給模塊指定別名

給模塊指定別名的通用語法:

import module_name as mn

8.6.5 導入模塊中的全部函數

使用星號(*)運算符可以讓Python導入模塊中的全部函數。
因爲導入了每一個函數,可經過名稱來調用每一個函數,而無需使用句點表示法。
然而,使用並不是本身編寫的大型模塊時,最好不要採用這種導入方法:若是模塊中有函數的名稱與你的項目中使用的名稱相同,可能致使意想不到的結果:Python可能遇到多個名稱相同的函數或變量,進而覆蓋函數,而不是分別導入全部的函數。
最佳的作法是,要麼只導入你須要使用的函數,要麼導入整個模塊並使用句點表示法。這能讓代碼更清晰,更容易閱讀和理解。
之因此介紹這種導入方法,只是想讓你在閱讀別人編寫的代碼時,若是遇到相似於下面的import語句,可以理解它們:

from module_name import *   
# 不推薦使用該種導入方法!!!

8.7 函數編寫指南

  • 應給函數指定描述性名稱,且只在其中使用小寫字母下劃線
  • 每一個函數都應包含簡要地闡述其功能的註釋,該註釋應緊跟在函數定義後面,並採用文檔字符串格式。
  • 若是形參不少,致使函數定義的長度超過了79字符,可在函數定義中輸入左括號後按回車鍵,並在下一行按兩次Tab鍵,從而將形參列表和只縮進一層的函數體區分開來。
  • 若是程序或模塊包含多個函數,可以使用兩個空行將相鄰的函數分開,這樣將更容易知道前一個函數在什麼地方結束,下一個函數從什麼地方開始。
  • 全部的import語句都應放在文件開頭,惟一例外的情形是,在文件開頭使用了註釋來描述整個程序。

9 類

9.3 繼承

9.3.1 子類的方法 __init__()

"""electric_car.py"""

class Car():
    """一次模擬汽車的簡單嘗試"""

    def __init__(self, make, model, year):
        self.make = make
        self.model = model
        self.year = year
        self.odometer_reading = 0

    def get_descriptive_name(self):
        long_name = str(self.year) + ' ' + self.make + ' ' + self.modes
        return long_name.title()

    def read_odometer(self):
        print("This car has " + str(self.odometer_reading) + " miles on in.")

    def update_odometer(self, mileage):
        if mileage >= self.odometer_reading:
            self.odometer_reading = mileage
        else:
            print("You can't roll back an odometer!")

    def increment_odometer(self, miles):
        self.odometer_reading += miles


class ElectricCar(Car):
    """電動汽車的獨特之處"""

    def __init__(self, make, model, year):
        """初始化父類的屬性"""
        super().__init__(make, model, year)


my_tesla = ElectricCar('tesla', 'model s', 2016)
print (my_tesla.get_descriptive_name())

建立子類時,父類必須包含在當前文件中,且位於子類前面。
定義子類時,必須在括號內指定父類的名稱。ElectricCar中方法__init__()接受建立Car實例所需的信息。
super()是一個特殊函數,幫助Python將父類和子類關聯起來。這行代碼讓Python調用ElectricCar的父類的方法__init__(),讓ElectricCar實例包含父類的全部屬性。父類也稱爲超類(superclass),名稱super所以而得名。

9.3.2 Python 2.7中的繼承

在Python 2.7中,繼承語法稍有不一樣,ElectricCar類的定義相似於下面這樣:

class Car(object):
    def __init__(self, make, model, year):
        --snip--

class ElectricCar(Car):
    def __init__(self, make, model, year):
        super(ElectricCar, self).__init__(make, model, year)
        --snip--

函數super()須要兩個實參:子類名和對象self。爲幫助Python將父類和子類關聯起來,這些實參必不可少。
另外,在Python 2.7中使用繼承時,務必在定義父類時在括號內指定object

9.3.4 重寫父類的方法

對於父類的方法,只要它不符合子類模擬的實物的行爲,均可對其進行重寫。爲此,可在子類中定義一個這樣的方法,即它與要重寫的父類方法同名。這樣,Python將不會考慮這個父類方法,而只關注你在子類中定義的相應方法。
假設Car類有一個名爲fill_gas_tank()的方法,它對全電動汽車來講毫無心義,所以你可能想重寫它。

def ElectricCar(Car):
    --snip-
    def fill_gas_tank():
        """電動汽車沒有油箱"""
        print("This car doesn't need a gas tank!")

如今,若是有人對電動汽車調用方法fill_gas_tank(),Python將忽略Car類中的方法fill_gas_tank(),轉而運行上述代碼。使用繼承時,可以讓子類保留從父類那裏繼承而來的精華,並剔除不須要的糟粕。

相關文章
相關標籤/搜索