Python學習筆記(語法篇)

blueStar_路漫發表於2020-02-17

本篇部落格大部分內容摘自埃裡克·馬瑟斯所著的《Python程式設計:從入門到實戰》(入門類書籍),採用舉例的方式進行知識點提要

關於Python學習書籍推薦文章 《學習Python必備的8本書》

Python語法特點:

  1. 通過縮排進行語句組織
  2. 不需要變數或引數的宣告
  3. 冒號

1 變數和簡單資料結構

1.1 變數命名

只能包含字母、數字和下劃線,且不能以數字打頭。

1.2 字串

在Python中,用引號括起的都是字串,其中的引號可以是單引號或雙引號

#示例1
"This is a string."
'This is also a string.'

#示例2
'I told my friend, "Python is my favorite language!"'
"The language 'Python' is named after Monty Python, not the snake."
"One of Python's strengths is its diverse and supportive community."
1.2.1 使用方法修改字串大小寫
#title()

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

Ada Lovelace  #輸出

#upper(),lower()

name = "Ada Lovelace"
print(name.upper())
print(name.lower())

ADA LOVELACE  #輸出
ada lovelace
1.2.2 合併(拼接)字串
#用‘+’實現

first_name = "ada"
last_name = "lovelace"
full_name = first_name+" "+last_name
message = "Hello, "+full_name.title()+"!" 
print(message) 
1.2.3 使用 /t or /n 新增空白

在程式設計中,空白泛指任何非列印字元,如空格、製表符和換行符。

>>>print("Languages:\n\tPython\n\tC\n\tJavaScript")

#輸出
Languages:
    Python
    C
    JavaScript
1.2.4 刪除空白
>>>favorite_language = ' python ' 

>>>favorite_language.rstrip() #剔除字串末尾的空白
' python'

>>>favorite_language.lstrip() #剔除字串開頭的空白
'python '

>>>favorite_language.strip() #剔除字串兩端的空白
'python'

1.3 數字

1.3.1 運算
>>>2+3
5
>>>3 - 2
1
>>>2 * 3
6
>>>3 / 2
1.5
>>>3 ** 2 #乘方運算
9
>>>2+3*4
14
>>>(2+3) * 4
20
1.3.2 使用函式str()避免型別錯誤
age = 23
message = "Happy "+str(age)+"rd Birthday!"
print(message)

#輸出
Happy 23rd Birthday!

2 列表

bicycles = ['trek', 'cannondale', 'redline', 'specialized']
print(bicycles)

#Python將列印列表的內部表示,包括方括號:
['trek', 'cannondale', 'redline', 'specialized']

2.1 訪問列表元素

bicycles = ['trek', 'cannondale', 'redline', 'specialized']
print(bicycles)

#輸出
trek

通過將索引指定為-1,可讓Python返回最後一個列表元素,類似地,索引-2返回倒數第二個列表元素,索引-3返回倒數第三個列表元素,以此類推。

bicycles = ['trek', 'cannondale', 'redline', 'specialized']
print(bicycles[-1])  #當且僅當列表為空時,會導致錯誤

#輸出
specialized

2.2 新增、刪除列表元素

2.2.1 新增元素

方法append() --向列表末尾新增元素

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

#輸出
['honda', 'yamaha', 'suzuki']  
['honda', 'yamaha', 'suzuki', 'ducati']

方法insert()–在列表的任何位置新增新元素

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

#輸出
['ducati', 'honda', 'yamaha', 'suzuki']
2.2.2 刪除元素

知道要刪除的元素在列表中的位置時,可使用del語句

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

#輸出
['honda', 'yamaha', 'suzuki']
['yamaha', 'suzuki']

方法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()只刪除第一個指定的值

2.3 組織列表

方法sort()–對列表進行永久性排序

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

#輸出
['audi', 'bmw', 'subaru', 'toyota']


#相反順序
cars = ['bmw', 'audi', 'toyota', 'subaru']
cars.sort(reverse=True)
print(cars)

['toyota', 'subaru', 'bmw', 'audi']  #輸出

函式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']

方法reverse()–反轉列表元素的排列順序

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

#輸出
['bmw', 'audi', 'toyota', 'subaru']
['subaru', 'toyota', 'audi', 'bmw']

函式len()–確定列表的長度

>>>cars = ['bmw', 'audi', 'toyota', 'subaru']
>>>len(cars)
4

3 操作列表

3.1 遍歷列表

for迴圈

magicians = ['alice', 'david', 'carolina'] 
for magician in magicians: 
    print(magician) 

#輸出
alice
david
carolina

3.2 建立數值列表

方法range(),Python在到達指定的第二個索引前面的元素後停止。

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

#輸出
1  
2
3
4

even_numbers = list(range(2,11,2))  #最後一個‘2’表示步長
print(even_numbers)

#輸出
[2, 4, 6, 8, 10]

利用方法range()建立數值列表的兩種方式:

numbers = list(range(1,6))
print(numbers)

#輸出
[2, 4, 6, 8, 10]

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

#輸出
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
3.2.1 對數值列表執行簡單的統計計算
>>>digits = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
>>>min(digits)
0
>>>max(digits)
9
>>>sum(digits)
45
3.2.2 列表解析
squares = [value**2 for value in range(1,11)]
print(squares)

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

#value**2:用於生成要儲存到列表中的值的表示式
#for迴圈:為表示式提供值,且for語句末尾不應有冒號

3.3 使用列表的一部分

3.3.1 切片
players = ['charles', 'martina', 'michael', 'florence', 'eli']
print(players[0:3]) #到達指定的第二個索引前面的元素後停止

#輸出也是一個列表
['charles', 'martina', 'michael']


"""沒有指定起始索引,Python從列表開頭開始提取"""
players = ['charles', 'martina', 'michael', 'florence', 'eli']
print(players[:4])

#輸出
['charles', 'martina', 'michael', 'florence']


"""省略終止索引,切片終止於結尾"""
players = ['charles', 'martina', 'michael', 'florence', 'eli']
print(players[2:])

#輸出
['michael', 'florence', 'eli']

players = ['charles', 'martina', 'michael', 'florence', 'eli']
print(players[-3:])  #列印列表最後3個元素
3.3.2 遍歷切片
players = ['charles', 'martina', 'michael', 'florence', 'eli']
print("Here are the first three players on my team:")
for player in players[:3]: 
    print(player.title())

#輸出
Here are the first three players on my team:
Charles
Martina
Michael
3.3.3 複製列表
#利用
my_foods = ['pizza', 'falafel', 'carrot cake']
friend_foods = my_foods[:]  #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 = ['pizza', 'falafel', 'carrot cake']
friend_foods = my_foods 
#新變數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', 'ice cream']
My friend's favorite foods are:
['pizza', 'falafel', 'carrot cake', 'cannoli', 'ice cream']

3.4 元組–不可變的列表

  • 用圓括號標識
  • 元素不可改,但可修改元組變數

4 if語句

#使用 and/or 檢查多個條件
#關鍵詞in檢查特定值是否包含在列表中,關鍵詞not in檢查特定值是否不包含在列表中
banned_users = ['andrew', 'carolina', 'david']
user = 'marie'
if user not in banned_users: 
    print(user.title()+", you can post a response if you wish.")

#輸出
Marie, you can post a response if you wish.

age = 12
if age < 4:
    price = 0
elif age < 18:
    price = 5
elif age < 65: 
    price = 10
else:            #else程式碼塊可省略
    price = 5
print("Your admission cost is $"+str(price)+".")


#在if語句中將列表名用在條件表示式中時
#Python將在列表至少包含一個元素時返回True,並在列表為空時返回False
requested_toppings = [] 
if requested_toppings: 
    for requested_topping in requested_toppings:
        print("Adding "+requested_topping+".")
    print("\nFinished making your pizza!")
else: 
    print("Are you sure you want a plain pizza?")

#輸出
Are you sure you want a plain pizza?

5 字典(一系列 鍵-值 對)

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

#輸出
green
5

對於較大的字典,可放在多行

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

5.1 使用字典

5.1.1 新增鍵-值對
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, 'y_position': 25, 'x_position': 0}

注意,鍵—值對的排列順序與新增順序不同。
Python不關心鍵—值對的新增順序,而只關心鍵和值之間的關聯關係。
5.1.2 刪除鍵-值對

利用del語句

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

#輸出
{'color': 'green', 'points': 5}
{'color': 'green'}

5.2 遍歷字典

5.2.1 遍歷所有的鍵-值對
user_0 = {
    'username': 'efermi',
    'first': 'enrico',
    'last': 'fermi',
    }
for key, value in user_0.items(): 
    print("\nKey: "+key) 
    print("Value: "+value) 

#輸出
Key: last
Value: fermi
Key: first
Value: enrico
Key: username
Value: efermi
5.2.2 遍歷所有鍵
favorite_languages = {
    'jen': 'python',
    'sarah': 'c',
    'edward': 'ruby',
    'phil': 'python',
    }
for name in favorite_languages.keys(): 
#替換為for name in favorite_languages:,輸出不變
#favorite_languages.keys()返回一個列表
    print(name.title())

#輸出
Jen
Sarah
Phil
Edward
5.2.3 遍歷所有值
favorite_languages = {
    'jen': 'python',
    'sarah': 'c',
    'edward': 'ruby',
    'phil': 'python',
    }
print("The following languages have been mentioned:")
for language in favorite_languages.values():
#可用set(favorite_languages.values())剔除重複項
    print(language.title())

#輸出
The following languages have been mentioned:
Python
C
Python
Ruby

5.3 巢狀

"""字典列表"""
alien_0 = {'color': 'green', 'points': 5}
alien_1 = {'color': 'yellow', 'points': 10}
alien_2 = {'color': 'red', 'points': 15}
aliens = [alien_0, alien_1, alien_2] 
for alien in aliens:
    print(alien)

#輸出
{'color': 'green', 'points': 5}
{'color': 'yellow', 'points': 10}
{'color': 'red', 'points': 15}


"""在字典中儲存列表"""
pizza = { 
    'crust': 'thick',
    'toppings': ['mushrooms', 'extra cheese'],
    }
print("You ordered a "+pizza['crust']+"-crust pizza "+
    "with the following toppings:")
for topping in pizza['toppings']: 
    print("\t"+topping)

#輸出
You ordered a thick-crust pizza with the following toppings:
    mushrooms
    extra cheese

"""在字典中儲存字典"""
users = {
    'aeinstein': {
        'first': 'albert',
        'last': 'einstein',
        'location': 'princeton',
        },
    'mcurie': {
        'first': 'marie',
        'last': 'curie',
        'location': 'paris',
        },
    }
for username, user_info in users.items(): 
    print("\nUsername: "+username) 
    full_name = user_info['first']+" "+user_info['last'] 
    location = user_info['location']
    print("\tFull name: "+full_name.title()) 
    print("\tLocation: "+location.title())

#輸出
Username: aeinstein
    Full name: Albert Einstein
    Location: Princeton
Username: mcurie
    Full name: Marie Curie
    Location: Paris

6 使用者輸入和while迴圈

6.1 使用者輸入

"""字串輸入-input()"""
prompt = "If you tell us who you are, we can personalize the messages you see."
prompt+= "\nWhat is your first name? "
name = input(prompt)
print("\nHello, "+name+"!")

 If you tell us who you are, we can personalize the messages you see.
What is your first name? Eric
Hello, Eric!


"""數值輸入-int()"""
>>>age = input("How old are you? ")
How old are you? 21
>>>age
'21'

6.2 while迴圈

for迴圈用於針對集合中的每個元素的一個程式碼塊,而while迴圈不斷地執行,直到指定的條件不滿足為止。

#示例1
current_number = 1
while current_number <= 5:
    print(current_number)
    current_number+= 1

#輸出 
1
2
3
4
5

#示例2
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)
6.2.1 使用while迴圈來處理列表和字典

for迴圈是一種遍歷列表的有效方式,但在for迴圈中不應修改列表,否則將導致Python難以跟蹤其中的元素。要在遍歷列表的同時對其進行修改,可使用while迴圈。

"""在列表之間移動元素"""
unconfirmed_users = ['alice', 'brian', 'candace'] 
confirmed_users = []
while unconfirmed_users: 
    current_user = unconfirmed_users.pop() 
    print("Verifying user: "+current_user.title())
    confirmed_users.append(current_user) 
print("\nThe following users have been confirmed:")
for confirmed_user in confirmed_users:
    print(confirmed_user.title())

#輸出
Verifying user: Candace
Verifying user: Brian
Verifying user: Alice
The following users have been confirmed:
Candace
Brian
Alice


"""刪除包含特定值的所有列表元素"""
pets = ['dog', 'cat', 'dog', 'goldfish', 'cat', 'rabbit', 'cat']
print(pets)
while 'cat' in pets:
    pets.remove('cat')
print(pets)

#輸出
['dog', 'cat', 'dog', 'goldfish', 'cat', 'rabbit', 'cat']
['dog', 'dog', 'goldfish', 'rabbit']

7 函式

7.1 傳遞實參

               """位置實參"""
def describe_pet(animal_type, pet_name): 
    print("\nI have a "+animal_type+".")
    print("My "+animal_type+"'s name is "+pet_name.title()+".")
describe_pet('hamster', 'harry') 

#輸出
I have a hamster.
My hamster's name is Harry.


               """關鍵字實參"""
def describe_pet(animal_type, pet_name):
    print("\nI have a "+animal_type+".")
    print("My "+animal_type+"'s name is "+pet_name.title()+".")
describe_pet(animal_type='hamster', pet_name='harry')

#輸出
describe_pet(animal_type='hamster', pet_name='harry')
describe_pet(pet_name='harry', animal_type='hamster')


               """預設值"""
#與c++相似,使用預設值時,在形參列表先列出沒有預設值的形參,而後列出有預設值的形參
def describe_pet(pet_name, animal_type='dog'):
    print("\nI have a "+animal_type+".")
    print("My "+animal_type+"'s name is "+pet_name.title()+".")
describe_pet(pet_name='willie')

#輸出
I have a dog.
My dog's name is Willie.
7.1.1 在函式中修改列表

將列表傳遞給函式後,函式就可對其進行修改。在函式中對這個列表所做的任何修改都是永久性的。

def print_models(unprinted_designs, completed_models): 
    """
    模擬列印每個設計,直到沒有未列印的設計為止
    列印每個設計後,都將其移到列表completed_models中
    """
    while unprinted_designs:
        current_design = unprinted_designs.pop()
        # 模擬根據設計製作3D列印模型的過程
        print("Printing model: "+current_design)
        completed_models.append(current_design)
def show_completed_models(completed_models): 
    """顯示列印好的所有模型"""
    print("\nThe following models have been printed:")
    for completed_model in completed_models:
        print(completed_model)
unprinted_designs = ['iphone case', 'robot pendant', 'dodecahedron']
completed_models = []
print_models(unprinted_designs, completed_models)
show_completed_models(completed_models)

#輸出
unprinted_designs = ['iphone case', 'robot pendant', 'dodecahedron']
completed_models = []
print_models(unprinted_designs, completed_models)
show_completed_models(completed_models)
7.1.2 禁止函式修改列表

可將列表的副本傳遞給函式

function_name(list_name[:])

7.2 傳遞任意數量的實參

def make_pizza(*toppings):
#形參名*toppings中的星號讓Python建立一個名為toppings的空元組
#並將收到的所有值都封裝到這個元組中
    """概述要製作的比薩"""
    print("\nMaking a pizza with the following toppings:")
    for topping in toppings:
        print("- "+topping)
make_pizza('pepperoni')
make_pizza('mushrooms', 'green peppers', 'extra cheese')

#輸出
Making a pizza with the following toppings:
- pepperoni
Making a pizza with the following toppings:
- mushrooms
- green peppers
- extra cheese

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

#形參**user_info中的兩個星號讓Python建立一個名為user_info的空字典
#並將收到的所有名稱—值對都封裝到這個字典中
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)

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

7.4 將函式儲存在模組中

               """"匯入整個模組"""
#pizza.py
def make_pizza(size, *toppings):
    """概述要製作的比薩"""
    print("\nMaking a "+str(size)+
          "-inch pizza with the following toppings:")
    for topping in toppings:
        print("- "+topping)
        
#making_pizzas.py
import pizza  #pizza.py中的所有函式將被複制到這個程式中
pizza.make_pizza(16, 'pepperoni') 
pizza.make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')

#輸出
Making a 16-inch pizza with the following toppings:
- pepperoni
Making a 12-inch pizza with the following toppings:
- mushrooms
- green peppers
- extra cheese


               """"匯入特定函式"""
from module_name import function_0, function_1, function_2

#as
import pizza as p
from pizza import make_pizza as mp


               """"匯入模組中的所有函式"""
from module_name import *

8 類

8.1 建立和使用類

8.1.1 建立類
class Dog(): 
#約定Python中,首字母大寫的名稱指的是類
    def __init__(self, name, age): 
        """初始化屬性name和age"""
        self.name = name 
        self.age = age
    def sit(self): 
        print(self.name.title()+" is now sitting.")
    def roll_over(self):
        print(self.name.title()+" rolled over!")
#類中的函式稱為方法
8.1.2 給屬性指定預設值
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):
        --snip--
    def read_odometer(self): 
        print("This car has "+str(self.odometer_reading)+" miles on it.")
my_new_car = Car('audi', 'a4', 2016)
print(my_new_car.get_descriptive_name())
my_new_car.read_odometer()

#輸出
2016 Audi A4
This car has 0 miles on it.
8.1.3 修改屬性的值
                """直接修改屬性的值"""
class Car():
    --snip--
my_new_car = Car('audi', 'a4', 2016)
print(my_new_car.get_descriptive_name())
my_new_car.odometer_reading = 23 
my_new_car.read_odometer()

#輸出
2016 Audi A4
This car has 23 miles on it.


                """通過方法修改屬性的值"""
class Car():
    --snip--
    def update_odometer(self, mileage): 
        """將里程錶讀數設定為指定的值"""
        self.odometer_reading = mileage
my_new_car = Car('audi', 'a4', 2016)
print(my_new_car.get_descriptive_name())
my_new_car.update_odometer(23) 
my_new_car.read_odometer()

#輸出
2016 Audi A4
This car has 23 miles on it.

8.2 繼承

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.model
        return long_name.title()
    def read_odometer(self):
        print("This car has "+str(self.odometer_reading)+" miles on it.")
    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):
    """Represent aspects of a car, specific to electric vehicles."""
    def __init__(self, make, model, year):
        """
        電動汽車的獨特之處
        初始化父類的屬性,再初始化電動汽車特有的屬性
        """
        super().__init__(make, model, year)
        self.battery_size = 70 
   def describe_battery(self): 
        print("This car has a "+str(self.battery_size)+"-kWh battery.")
my_tesla = ElectricCar('tesla', 'model s', 2016)
print(my_tesla.get_descriptive_name())
my_tesla.describe_battery()

#輸出
2016 Tesla Model S
This car has a 70-kWh battery.
8.2.1 將例項用作屬性
class Car():
    --snip--
class Battery(): 
    def __init__(self, battery_size=70): 
        self.battery_size = battery_size
    def describe_battery(self):
        print("This car has a "+str(self.battery_size)+"-kWh battery.")

class ElectricCar(Car):
    def __init__(self, make, model, year)
        super().__init__(make, model, year)
        self.battery = Battery() #將例項用作屬性

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

#輸出
2016 Tesla Model S
This car has a 70-kWh battery.

8.3 匯入類

           """匯入單個類"""
from 檔名(無字尾'.py') import 類名
           """匯入多個類"""
from 檔名(無字尾'.py') import 類名,類名
           """匯入整個模組"""
import 檔名(無字尾'.py')
        """匯入模組中的所有類"""
from 檔名(無字尾'.py') import *   (不提倡)

掌握匯入函式和類的各種方法後,即可使用Python標準庫(一組模組)中的任何函式和類,達到事半功倍的效果。
要了解Python標準庫,有一個不錯的網站 Python Module of the Week

9 檔案和異常

9.1 檔案的開啟

檔案開啟模式 描述
‘r’ 只讀,預設值,檔案不存在則報錯
‘w’ 覆蓋寫,檔案不存在則建立
‘x’ 建立寫,建立檔案寫,檔案已存在則報錯
‘a’ 追加寫,檔案不存在則建立
‘b’ 二進位制檔案模式
‘t’ 文字檔案模式
‘+’ 與 r/w/x/a 一同使用,在原功能基礎上增加同時讀寫功能,另:'r+'與’w+’功能類似,可讀,覆蓋寫,但檔案不存在時將報錯

<檔名> = open(檔案路徑/檔名,<開啟模式>)
’rb’,為檔案預設開啟模式。

file_path = 'C:\Users\ehmatthes\other_files\text_files\filename.txt'
with open(file_path) as file_object:

#絕對檔案路徑示例,Windows系統使用反斜槓‘\’
#反斜槓在Python中被視為轉義標記,為確保萬無一失,可採用以下形式:

file_path = r'C:\Users\ehmatthes\other_files\text_files\filename.txt'

file_path = 'C:\\Users\\ehmatthes\\other_files\\text_files\\filename.txt'

9.2 從檔案中讀取資料

操作方法 描述
f.read(size) 引數省略,讀入全部內容;給出引數,讀入前size長度
f.readline(size) 引數省略,讀入一行內容;給出引數,讀入該行前size長度
f.readlines(hint) 引數省略,讀入檔案所有行,以每行為元素形成列表;給出引數,讀入前hint行
9.2.1 讀取整個檔案
#pi_digits.txt
3.1415926535
  8979323846
  2643383279

#file_reader.py
with open('pi_digits.txt') as file_object:
#關鍵詞 with在不再需要訪問檔案後將其關閉,且open()返回的檔案物件只在with程式碼塊內可用
    contents = file_object.read()
    print(contents)

#輸出
3.1415926535
  8979323846
  2643383279
   
#read()到達檔案末尾時返回一個空字串,要刪除可在print語句中使用rstrip()
9.2.2 檔案的逐行操作
              """逐行讀取,逐行處理"""
filename = 'pi_digits.txt' 
with open(filename) as file_object: 
    for line in file_object: 
        print(line)

#輸出會產生更多空行:每行末尾都有一個看不見的換行符,print語句也會加上一個換行符。
#為消去多餘的空白行,仍可在print語句中使用rstrip()


            """一次讀入,分行處理"""
filename = 'pi_digits.txt'
with open(filename) as file_object:
    lines = file_object.readlines()  
    #將讀取結果存入lines,以便在with程式碼塊外使用
for line in lines: 
    print(line.rstrip())

#輸出內容與檔案內容完全一致

9.3 寫入檔案

操作方法 描述
f.write(s) 向檔案寫入一個字串或位元組流,它不會在寫入的文字末尾新增換行符
f.writelines(s) 將一個元素全為字串的列表寫入檔案
f.seek(offset) 改變當前檔案操作指標的位置,引數含義:0-檔案開頭,1-當前位置,2-檔案結尾

注意:Python只能將字串寫入文字檔案。要將數值資料儲存到文字檔案中,必須先使用函式str()將其轉換為字串格式。

filename = 'pi_digits.txt'
ls=['中國','法國','美國']
with open(filename,'w+') as file_object:
    file_object.writelines(ls)
    file_object.seek(0)
    for line in file_object:
        print line

#輸出
中國法國美國

9.4 異常

異常:Python建立的特殊物件,用於管理程式執行是出現的錯誤。

若未對異常進行處理,程式將停止,顯示有關異常的報告;若編寫了處理異常的程式碼,程式將繼續執行。

try:
     Normal execution block
except A:
     Exception A handle/pass
except B:
     Exception B handle/pass
except:
     Other exception handle/pass
else:
     if no exception,get here
finally:
     print("finally")
#pass讓Python什麼都不要做

try:可能產生異常的語句
except 捕獲並處理異常,通常異常有不同型別,可分別處理
else:try語句塊正常執行時,無異常產生,執行else語句塊
finally:無論是否有異常產生,均執行

#示例1
try:
    print(5/0)
except ZeroDivisionError:
    print("You can't divide by zero!")

#輸出
You can't divide by zero!


#示例2
def count_words(filename):
    """計算一個檔案大致包含多少個單詞""" 
    try:
        with open(filename) as f_obj:
            contents = f_obj.read()
    except FileNotFoundError:
        msg = "Sorry, the file "+filename+" does not exist."
        print(msg)
    else:
        # 計算檔案大致包含多少個單詞
        words = contents.split()
        #方法split()以空格為分隔符將字串分拆成多個部分,並將這些部分都儲存到一個列表中。
        num_words = len(words)
        print("The file "+filename+" has about "+str(num_words)+
            " words.")
filename = 'alice.txt'
count_words(filename)

9.5 儲存資料

模組json:能儲存使用者資料,以免在程式停止執行後丟失。模組json可將簡單的Python資料結構轉儲到檔案中,並在程式再次執行時載入該檔案中的資料。

9.5.1 使用json.dump()和json.load()
#number_writer.py
import json  
numbers = [2, 3, 5, 7, 11, 13]
filename = 'numbers.json' #注意這裡的檔案擴充名 
with open(filename, 'w') as f_obj: 
    json.dump(numbers, f_obj) 
    #json.dump()的兩個實參分別是要儲存的資料以及可用於儲存資料的檔案物件

#number_reader.py
import json
filename = 'numbers.json' 
with open(filename) as f_obj: 
    numbers = json.load(f_obj) 
print(numbers)

#輸出
[2, 3, 5, 7, 11, 13]

#以上演示表明這是一種在程式之間共享資料的簡單方式

10 測試程式碼

10.1 測試函式

#name_function.py
def get_formatted_name(first, last, middle=''):
    if middle:
        full_name = first+' '+middle+' '+last
    else:
        full_name = first+' '+last
    return full_name.title()

#test_name_function.py
import unittest
from name_function import get_formatted_name
class NamesTestCase(unittest.TestCase):
#這個類必須繼承unittest.TestCase類
    def test_first_last_name(self):
    #方法名必須以test_打頭,這樣才會在執行該程式時自動執行
        formatted_name = get_formatted_name('janis', 'joplin')
        self.assertEqual(formatted_name, 'Janis Joplin')
        #斷言方法assertEqual()用以核實得到的結果是否與期望的結果一致
    def test_first_last_middle_name(self):        
        formatted_name = get_formatted_name( 'wolfgang', 'mozart', 'amadeus')
        self.assertEqual(formatted_name, 'Wolfgang Amadeus Mozart')
if __name__=="__main__":
     unittest.main()

#輸出
..
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OK

執行測試用例時,每完成一個單元測試,Python都列印一個字元:測試通過時列印一個句點;測試引發錯誤時列印一個E;測試導致斷言失敗時列印一個F。

10.2 測試類

10.2.1 各種斷言方法
方法 用途
assertEqual(a,b) 核實a==b
assertNotEqual(a,b) 核實a!=b
assertTrue(x) 核實x為True
assertFalse(x) 核實x為False
assertIn(item,list) 核實item在list中
assertNotIn(item,list) 核實item不在list中
10.2.2 測試示例
#survey.py
class AnonymousSurvey():
    """收集匿名調查問卷的答案"""
    def __init__(self, question): 
        """儲存一個問題,併為儲存答案做準備"""
        self.question = question
        self.responses = []
    def show_question(self): 
        """顯示調查問卷"""
        print(self.question)
    def store_response(self, new_response): 
        """儲存單份調查答卷"""
        self.responses.append(new_response)
    def show_results(self): 
        """顯示收集到的所有答卷"""
        print("Survey results:")
        for response in self.responses:
            print('- '+response)

#test_survey.py
import unittest
from survey import AnonymousSurvey
class TestAnonymousSurvey(unittest.TestCase):
    def test_store_single_response(self):
        question = "What language did you first learn to speak?"
        my_survey = AnonymousSurvey(question) 
        my_survey.store_response('English')
        self.assertIn('English', my_survey.responses) 
    def test_store_three_responses(self):
        question = "What language did you first learn to speak?"
        my_survey = AnonymousSurvey(question)
        responses = ['English', 'Spanish', 'Mandarin'] 
        for response in responses:
            my_survey.store_response(response)
        for response in responses: 
            self.assertIn(response, my_survey.responses)
if __name__=="__main__":
     unittest.main()

#輸出
..
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OK
10.2.3 方法setUp()
#test2_survey.py
import unittest
from survey import AnonymousSurvey
class TestAnonymousSurvey(unittest.TestCase):
    def setUp(self):
        question = "What language did you first learn to speak?"
        self.my_survey = AnonymousSurvey(question) 
        self.responses = ['English', 'Spanish', 'Mandarin'] 
        #Python將先執行方法setUp(),再執行各個以test_打頭的方法。
    def test_store_single_response(self):
        self.my_survey.store_response(self.responses[0])
        self.assertIn(self.responses[0], self.my_survey.responses)
    def test_store_three_responses(self):
        for response in self.responses:
            self.my_survey.store_response(response)
        for response in self.responses:
            self.assertIn(response, self.my_survey.responses)
if __name__=="__main__":
     unittest.main()

相關文章