第二章 變量和簡單數(shù)據(jù)類型
運行py文件時發(fā)生的情況
運行hello_world.py文件時洋满,末尾的.py指出這是一個Python程序仿荆,因此編輯器將使用Python解釋器來運行它孕讳。Python解釋器讀取整個程序涣易,確定每個單詞的含義良哲。例如print锹引,解釋器就將括號里的內(nèi)容打印到屏幕上矗钟。
變量名只能包含字母、數(shù)字和下劃線嫌变,不能以數(shù)字開頭吨艇,而且應該全部小寫。
字符串拼接
first_name = 'ada'
last_name = 'lovelace'
full_name = first_name + " " + full_name
使用制表符或換行符來添加空白
print("Languages:\n\tPython\n\tJavaScript")
刪除空白
favorite_language = 'python '
favorite_language.rstrip()
strip()和lstrip()是刪除開頭的空格
rstrip()是刪除結(jié)尾的空格
第三章 列表
列表簡介
bicycles = ['trek', 'cannondale', 'redline', 'specialized']
列表是有序集合腾啥,因此要訪問列表的任何元素芭概,只需要將元素的位置或者索引告訴Python即可。
索引是從0開始
索引的最后一個是-1儡率,倒數(shù)第二個是-2,以此類推组贺。
修改列表元素
motocycles = ['honda', 'yamaha', 'suzuki']
mococycles[0]='ducati'
添加元素
1、在末尾添加
motocycles = [] #先創(chuàng)建空的列表
motocycles.append('ducati')
2祖娘、在列表中插入元素
motocycles = ['honda', 'yamaha', 'suzuki']
motocycles.insert(1, 'ducati')
方法insert()在索引1處添加空間失尖,并將值'ducati'存儲到這個地方。這種操作將列表中排序1之后的每個元素都右移一個位置渐苏。
3掀潮、從列表中刪除元素
motocycles = ['honda', 'yamaha', 'suzuki']
del motocycles[0]
pop刪除
motocycles.pop()
彈出列表最后一個元素
彈出特定位置元素
motocycles.pop(1) #彈出第二個元素
被彈出的元素可以繼續(xù)復制使用
比如first_owned = motocycles.pop(0)
雖然列表中沒有該元素,但是該元素值可以繼續(xù)使用
4整以、根據(jù)值刪除元素
motocycles = ['honda', 'yamaha', 'suzuki']
motocycles.remove('honda')
組織列表
sort()對列表進行永久排序
sort(reverse=True)倒序排序
sorted()對列表進行臨時排序胧辽,原來的列表的順序并沒有變
reverse()反轉(zhuǎn)列表,這里的反轉(zhuǎn)是指元素的排列順序反轉(zhuǎn)
len()確定列表的長度
第四章 操作列表
遍歷列表list
motocycles = ['honda', 'yamaha', 'suzuki']
for moto in motocycles:
print(moto)
創(chuàng)建數(shù)字列表
使用函數(shù)range()公黑,range()讓你能夠生成一系列的數(shù)字。
for value in range(1,5):
print(value)
打印不包括5
要創(chuàng)建數(shù)字列表摄咆,可以使用函數(shù)list()將range()的結(jié)果直接轉(zhuǎn)換為列表凡蚜。
numbers = list(range(1,5))
print(numbers)
[1,2,3,4]
range()還可以指定步長,如range(2,11,2),從2開始吭从,不斷的加2朝蜘,直到11(不包括11)
數(shù)字列表的簡單計算
min(numbers)
max(numbers)
sum(numbers)
使用列表的一部分
切片
列表的部分元素-Python稱之為切片
players = ['charles', 'martina', 'michael, 'florence', 'eli']
提取第2-4個元素。
players[1:4]
如果沒有指定第一個索引涩金,那就是從開頭開始
players[:4]
如果沒有指定第二個索引谱醇,那就直接到末尾
players[2:]
負數(shù)索引能夠讓你輸出特定位置到列表末尾的所有元素
players[-2:]
將輸出-1,-2兩個元素
遍歷切片
for player in players[1:3]:
print player
復制列表
假如我喜歡的食物步做,有一個朋友也喜歡副渴,然后我喜歡的列表多了一樣,朋友喜歡的也多了一樣全度。
剛開始三樣一樣煮剧,如何復制列表?
my_foods =['pizza', 'falafel', 'carrot cake']
friend_foods = my_foods
my_foods.append('cannoli')
friend_foods.append('ice cream')
print(my_foods)
print(friend_foods)
你會發(fā)現(xiàn)将鸵,這兩個列表輸出的一模一樣勉盅,而且cannoli和ice cream都在列表里面。為什么呢顶掉,因為friend_foods = my_foods并沒有復制列表草娜,而只是新建了一個friend_foods變量,關(guān)聯(lián)到原來的my_foods上痒筒。所以宰闰,改動其實是在一個列表上嗜暴。
那如何正確復制?利用切片议蟆。
my_foods =['pizza', 'falafel', 'carrot cake']
friend_foods = my_foods[:]
my_foods.append('cannoli')
friend_foods.append('ice cream')
print(my_foods)
print(friend_foods)
元組tuple
列表可以動態(tài)調(diào)整闷沥,使得滿足各種需求,如果你有不變的列表咐容,那這樣的列表可以被稱為元組舆逃。
定義元組
元組看起來和列表類似,區(qū)別在于元組是圓括號戳粒,列表是方括號路狮。
dimensions = (200, 50)
dimensions[0] = 250
這里復制會報錯,因為tuple不能被改變
遍歷元組
for dimension in dimensions:
print(dimension)
雖然不能更改單個元組某個元素的值蔚约,但是可以更改整個元組的值奄妨。
dimensions = (200, 50)
dimensions = (400, 100)
這里并不會報錯。
第五章 if語句
判斷相等 ==
判斷不等 !=
檢查特定值是否包含在列表中
request_topping=['mushrooms', 'onions', 'pineapple']
'mushrooms' in request_toppings
判斷特定值是否不包含在列表中
if 'mushrooms' not in request_toppings:
if else
if elif else
if
第六章 字典
字典:包含key-value鍵值對的數(shù)據(jù)結(jié)構(gòu)苹祟。
alien={'color':'green', 'points':5}
可將任何字段用作key砸抛,包括數(shù)字、字符串树枫、列表乃至字典直焙。
訪問字典中的值
alien['color']
添加鍵值對
alien['x_position']=0
alien['y_position']=250
空字段
alien={}
修改字典中的值
alien['color']=‘yellow'
刪除鍵值對
del alien['points']
遍歷字典
for key,value in alien:
print(key,value)
注意,鍵值對返回的順序和存儲順序不同砂轻,Python不關(guān)心鍵值對的存儲順序奔誓,而只關(guān)心鍵值對之間的關(guān)聯(lián)關(guān)系。
遍歷字典中的所有鍵
for key in alien.keys():#for key in alien效果一樣
按順序遍歷字典中所有鍵
要以特定的順序返回元素搔涝,一種方法是在for循環(huán)中對返回的鍵進行排序厨喂,為此,可以用sorted()來排序
for key in sorted(alien.keys()):
遍歷字典中所有值
for value in alien.values():
如果值有重復庄呈,那輸出重復的值沒有意義蜕煌,如何去重:可以使用集合
for value in set(alien.values()):
嵌套
字典列表
alien_0={'color':'green', 'points':5}
alien_1={'color':'yellow', 'points':10}
aliens = [alien_0, alien_1]
在字典中存儲列表
pizza = {'crust':'thick', 'topping': ['mushroom','extra cheese'],}
在字典中存儲字典
用戶輸入和while循環(huán)
name = input("Please enter your name:")
print(name)
input()將用戶輸入解讀為字符串
如果輸入的是數(shù)字字符串,可以通過int()將其轉(zhuǎn)化成數(shù)字
求模運算符
4%3
求模運算符抒痒,將兩個數(shù)相除并符合余數(shù)幌绍。
active = True
while active:
message=input()
if message == 'quit':
active = False
else:
print(message)
另一種寫法:break
使用break退出循環(huán)
while True:
message=input()
if message == 'quit':
break
else:
print(message)
continue:繼續(xù)使用循環(huán),從頭開始執(zhí)行
打印10以內(nèi)的奇數(shù)
current_number = 0
while current_number < 10:
current_number += 1
if current_number % 2 == 0:
continue
print(current_number)
for循環(huán)是一種遍歷列表的有效方式故响,但在for循環(huán)中不應該修改列表傀广,否則將導致python難以跟蹤其中元素。如果要在遍歷列表的同時對其修改彩届,可以使用while循環(huán)伪冰。
unconfirmed_users = ['alice','brain', 'candace']
while unconfirmed_users:
current_user = unconfirmed_users.pop()
刪除包含特定值的所有列表元素
pets = ['dog','cat','dog','goldfish','cat','rabbit','cat']
while 'cat' inpets:
pets.remove('cat')
函數(shù)
def greet_user(username):
print("hello!," + username.title() + "!")
greet_user('sarah')
實參和形參
username是一個形參,'sarah'是一個實參樟蠕。將實參'sarah'傳遞給函數(shù)的形參username,值被存儲在形參username中贮聂。
位置實參
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('dog', 'willie')
調(diào)用函數(shù)時靠柑,Python必須將函數(shù)調(diào)用中的每個實參都關(guān)聯(lián)到函數(shù)定義中的一個形參,最簡單的關(guān)聯(lián)方式就是基于實參的順序吓懈。這種關(guān)聯(lián)方式稱為位置實參歼冰。
關(guān)鍵字實參
關(guān)鍵字實參是傳遞給函數(shù)的名稱-值對。你直接在實參中將名稱和值關(guān)聯(lián)起來耻警。因此向函數(shù)傳遞實參時不會混淆隔嫡。關(guān)鍵字實參讓你無需考慮函數(shù)調(diào)用中的實參順序,還清楚的指出了函數(shù)調(diào)用中各值的用途甘穿。
describe_pet(animal_type = 'dog', pet_name = 'willie')
默認值
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')
也可以通過位置實參調(diào)用
describe_pet('willie')
使用默認值時腮恩,在形參列表中必須先列出沒有默認值的形參,再列出有默認值的形參温兼。這讓Python依然能夠正確解讀位置參數(shù)秸滴。
返回值
def get_formatted_name(first_name, last_name):
full_name = first_name + ' ' + last_name
return full_name.title()
返回字典
def build_person(first_name,last_name):
person = {'first_name':first_name,'last_name':last_name}
return person
禁止函數(shù)修改列表
有時候,我們需要禁止修改列表募判。為了解決這個問題荡含,可以向函數(shù)傳遞列表的副本,而不是列表本身兰伤,這樣對列表的修改只是在副本上内颗。不會影響列表本身。也就是傳遞列表的切片
function(last_name(:))
傳遞任意數(shù)量的實參
一個制作披薩的函數(shù)敦腔,它需要接受很多配料,但你無法預先確定顧客要多少種配料恨溜。
def make_pizza(*toppings):
for topping in toppings:
print("- " + topping)
make_pizza('pepperoni')
make_pizza('mushrooms','green peppers','extra cheese')
形參名*toppings中的星號讓Python創(chuàng)建一個名為toppings的空元組符衔,并將收到的所有值都封裝到這個元組中。
結(jié)合使用位置實參和任意數(shù)量實參
如果要讓函數(shù)接受不同類型的實參糟袁,必須在函數(shù)定義中將接納任意數(shù)量實參的形參放在最后判族。Python先匹配位置實參和關(guān)鍵字實參,再將余下的實參都收集到最后一個形參中项戴。
def make_pizza(size, *toppings):
print("\nMaking a "+ str(size) + "-inch pizza with following toppings:")
for topping in toppings:
print("- " + topping)
make_pizza(16,'pepperoni')
基于函數(shù)定義形帮,Python將第一個值存儲在形參中,并將其他所有值存儲在元組toppings中周叮。
使用任意數(shù)量的關(guān)鍵字實參
def build_profile(first, last, **user_info):
profile={}
profile['first_name'] = first
profile['last_name'] = last
for key,value in user_info:
profile[key] = value
return profile
build_profile('albert', 'einstein', location='princeton', field='physics')
函數(shù)的定義要求提供名和姓辩撑,同時允許用戶根據(jù)需要提供任意數(shù)量的名稱-鍵值對,形參*user_inmfo中的兩個號讓Python創(chuàng)建一個名為user_info的空字典仿耽。并將收到的所有鍵值對都封裝到這個字典中合冀。可以像訪問其他字典那樣訪問user_info鍵值對
將函數(shù)存儲在模塊中项贺,可以通過import來使用模塊中的函數(shù)
導入整個模塊
pizza.py
def make_pizza(size, *toppings):
print("\nMaking a "+ str(size) + "-inch pizza with following toppings:")
for topping in toppings:
print("- " + topping)
我們在pizza.py目錄創(chuàng)建另一個making_pizzas.py文件君躺,導入pizzs模塊峭判,再調(diào)用make_pizza()兩次
making_pizzas.py
import pizza
pizza.make_pizza(16, 'pepperoni')
pizza.make_pizza(12, 'mushrooms','green peppers','extra cheese')
Python讀取這個文件時,代碼行import pizza讓Python打開文件pizza.py棕叫,并將其中的所有的函數(shù)都復制到這個程序中林螃。調(diào)用方法就是模塊名,后面加.俺泣,最后再加函數(shù)名
module_name.fuction_name()
導入特定函數(shù)
from module_name import fuction_name0, fuction_name1
通過這種方式導入的函數(shù)疗认,可以直接用fuction_name0()進行調(diào)用
使用as給指定函數(shù)指定別名
如果要導入的函數(shù)的名稱可能與程序中的現(xiàn)有名稱沖突,或者函數(shù)名稱太長砌滞,可指定簡短且獨一無二的別名侮邀。
from module_name import function_name as fn
from pizza import make_pizza as mp
mp(16, 'pepperoni')
mp(12, 'mushrooms','green peppers','extra cheese')
使用as給模塊指定別名
import module_name as mn
import pizza as p
p.make_pizza(16, 'pepperoni')
p.make_pizza(12, 'mushrooms','green peppers','extra cheese')
導入模塊中所有函數(shù)
from pizza import *
make_pizza(16, 'pepperoni')
make_pizza(12, 'mushrooms','green peppers','extra cheese')
import語句中的*讓Python將模塊pizza中的每個函數(shù)都復制到這個程序文件中。由于導入了每個函數(shù)贝润,可通過名稱來調(diào)用每個函數(shù)绊茧,而無需使用句點表示法。然而打掘,使用并非自己編寫的大型模塊時华畏,最好不要采用這種導入方法:如果模塊中有函數(shù)的名稱與你的項目中使用的名稱相同,可能導致意想不到的結(jié)果:Python可能遇到多個名稱相同的函數(shù)活變量尊蚁,進而覆蓋函數(shù)亡笑,而不是分別導入所有的函數(shù)。
最佳的做法是横朋,要么只導入你需要用的函數(shù)仑乌,要么導入整個模塊并使用句點法
函數(shù)編寫指南
1、函數(shù)名稱只用小寫字母和下劃線
2琴锭、函數(shù)都應包含簡要闡述期功能的注釋
3决帖、參數(shù)的意義的注釋
第九章 類
創(chuàng)建dog類
class Dog():
"""一次模擬小狗的簡單嘗試"""
def __init__(self, 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.")
方法 init()
類中的函數(shù)稱為方法厕九,init()是一個特殊的方法地回,每當你根據(jù)Dog類創(chuàng)建新實例時扁远,Python就會自動運行它。在這個方法的名稱中,開頭和結(jié)尾各有兩個下劃線购公,這是一種約定,旨在避免Python默認方法與普通方法發(fā)生沖突靠瞎。
init()包含三個形參父能,self爱榕、name和age藻三。在這個方法的定義中柜蜈,形參self必不可少,還必須位于其他形參的前面。因為Python調(diào)用init()方法創(chuàng)建Dog實例時,將自動傳入實參self。每個與類相關(guān)聯(lián)的方法調(diào)用都自動傳遞實參self黎棠,它是指向?qū)嵗旧淼囊茫寣嵗軌蛟L問類中的屬性和方法关翎。我們創(chuàng)建Dog實例時,Python將調(diào)用Dog類的方法,init()昌简,我們將通過實參向Dog()傳遞名字和年齡,self會自動傳遞晚顷。
init方法里面兩個變量都有前綴self,以self為前綴的變量都可供類中的所有方法使用恋沃,我們還可以通過類的任何實例訪問這些變量。self.name=name獲取存儲在形參name中的值户辞,并將其存儲到變量name中双仍,然后將該變量關(guān)聯(lián)到當前創(chuàng)建的實例茅诱。像這樣可通過實例訪問的變量稱為屬性秀睛。
Dog類還定義了另外兩個方法:sit()和roll_over()锐帜。由于這些方法不需要額外的參數(shù)痹升,因此他們只有一個形參self肛跌。
根據(jù)類創(chuàng)建實例
my_dog = Dog('willie', 6)###調(diào)用init()創(chuàng)建特定小狗實例
print("My dog's name is " + my_dog.name.title() + ".")
print("My dog's is " + str(my_dog.age) + " years old.")
訪問屬性
要訪問實例的屬性驯嘱,可使用句點法表示。my_dog.name
調(diào)用方法
my_dog.sit()
使用類和實例
class Car():
"""一次模擬汽車的簡單嘗試"""
def __init__(self, make, model, year):
self.make = make
self.model = model
self.year = year
def get_descriptive_name(self):
long_name = str(self.year) + ' ' + self.make + ' ' + self.model
return long_name.title()
my_new_car = Car("audi", "a4", 2016)
給屬性指定默認值
class Car():
"""一次模擬汽車的簡單嘗試"""
def __init__(self, make, model, year):
self.make = make
self.model = model
self.year = year
self.odometer = 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.")
修改屬性的值
my_new_car.odometer = 23
my_new_car.read_odometer()
通過方法修改屬性的值
class Car():
"""一次模擬汽車的簡單嘗試"""
def __init__(self, make, model, year):
self.make = make
self.model = model
self.year = year
self.odometer = 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):
self.odomter = mileage
my_new_car.update_odometer(23)
通過方法對屬性的值進行遞增
def increment_odometer(self, miles):
self.odometer += miles
my_new_car.increment_odometer(50)
class Car():
"""一次模擬汽車的簡單嘗試"""
def __init__(self, make, model, year):
self.make = make
self.model = model
self.year = year
self.odometer = 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):
self.odomter = mileage
def increment_odometer(self, miles):
self.odometer += 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())
創(chuàng)建子類時喳坠,父類必須包含在當前文件中鞠评,且位于子類之前。
super()函數(shù)是一個特殊函數(shù)壕鹉,幫助Python將父類和子類關(guān)聯(lián)起來剃幌。
給子類定義屬性和方法
class Car():
"""一次模擬汽車的簡單嘗試"""
def __init__(self, make, model, year):
self.make = make
self.model = model
self.year = year
self.odometer = 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):
self.odomter = mileage
def increment_odometer(self, miles):
self.odometer += miles
class ElectricCar(Car):
"""電動汽車的獨特之處"""
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.describe_battery()
重寫父類方法
假設Car類有一個名為fill_gas_tank()的方法,它對電動汽車毫無意義晾浴,因此可以重寫他
class ElectricCar(Car):
--snip--
def fill_gas_tank(self):
print("This car doesn't need a gas tank!")
將實例用作屬性
可能需要將類的一部分作為一個獨立的類提取出來负乡。可以將大型類拆分成多個協(xié)同工作的小類脊凰。
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()
導入類
由于類不斷的添加功能抖棘,文件變的很長,為了讓文件盡可能整潔,Python允許你將類存儲在模塊中切省,然后在主程序中導入所需模塊
導入單個類
car.py
"""一個可用于表示汽車的類"""
class Car():
"""一次模擬汽車的簡單嘗試"""
def __init__(self, make, model, year):
self.make = make
self.model = model
self.year = year
self.odometer = 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):
self.odomter = mileage
def increment_odometer(self, miles):
self.odometer += miles
my_car.py
from car import Car##從文件中導入類最岗,可用利用逗號,一次引入多個類
my_new_car = Car('audi', 'a4', 2016)
print(my_new_car.get_descriptive_name())
my_new_car.odometer = 23
my_new_car.read_odometer()
導入整個模塊
可用import car導入整個模塊朝捆。接下來般渡,我們使用module_name.class_name訪問需要的類
導入模塊所有類
from car import *
不推薦這種導入方式,其原因有二:
1芙盘、如果只要看一下文件開頭的import語句驯用,就能清楚知道程序使用了哪些類,將大有裨益何陆。但這種方式并沒有明確你使用了模塊中哪些類
2晨汹、這種導入方式還可能引發(fā)名稱方面的困惑。如果你不小心導入了一個與程序文件中其他同名的類贷盲,可能引發(fā)錯誤淘这。
在一個模塊中引入另一個模塊
這個用法和普通的模塊引入沒有任何區(qū)別,比如把Car類和ElectricCar分成兩個模塊文件巩剖,任何在ElectricCar里面from car import Car
后面如果需要導入Car和ElectricCar類的時候铝穷,不能以為ElectricCar類里面導入了Car就不需要再導入了。所以佳魔,Car類和ElectricCar類都需要單獨導入曙聂。
類編碼風格
1、類名應采取駝峰命名法鞠鲜,將類名中的每個首字母大寫宁脊,而不使用下劃線。實例名和模塊名都是小寫格式贤姆,并在單詞之間加上下劃線榆苞。
2、對于每個類霞捡,都應緊跟在類定義后面包含一個文檔字符串坐漏。描述累的功能。每個模塊也都要包含一個文檔字符串碧信,對其中的類的行為進行描述
3赊琳、在類中,可使用一個空行來分隔方法砰碴;而在模塊中躏筏,可使用兩個空行來分隔類。
4呈枉、需要同時導入標準庫中的模塊和你自己編寫的模塊時寸士,先導入標準庫模塊的import語句檐什,再添加一個空行,然后再編寫導入你自己編寫的模塊的import語句弱卡。這種做法讓人更容易明白程序使用的各個模塊來自何方。
總結(jié):
除了類名是駝峰命名法住册,首字母大寫婶博,其他比如實例、模塊名荧飞、函數(shù)名凡人、方法名、變量名都是小寫加下劃線叹阔,導入變量名還可以加數(shù)字挠轴。
第十章 文件和異常
with open('pi_digits.txt') as file_object:
contents = file_object.read()
print(contents)
這里有調(diào)用open(),但是沒有調(diào)用close()耳幢。用with打開文件岸晦,Python會自動在合適的時候調(diào)用close()關(guān)閉文件。
這個輸出會多一行睛藻,原因在于read()到達文件末尾時返回一個空字符串启上,而將這個空字符串顯示出來就是一個空行。要刪除空行店印,可以在print里面使用rstrip()
print(contents.rstrip())
上面的open的文件沒有帶路徑冈在,Python會自動搜索程序文本所在的當前文件夾。
文件路徑
相對路徑
linux和os x系統(tǒng)
with open('text_files/filename.txt') as file_object
windows系統(tǒng)
with open('text_files\filename.txt') as file_object
絕對路徑
linux和os x系統(tǒng)
file_path = '/home/ehmatthes/text_files/filename.txt'
with open(file_path) as file_object
windows系統(tǒng)
file_path = 'C:\Users\ethmatthes\other_files\text_files\filename.txt'
with open(file_path) as file_object
逐行讀取
filename = 'pi_digits.txt'
with open(filename) as file_object:
for line in file_object:
print(line.rstrip())
調(diào)用open后按摘,將一個表示文件及其內(nèi)容的對象存儲到變量file_object中包券。
創(chuàng)建一個包含文件各行內(nèi)容的列表
filename = 'pi_digits.txt'
with open(filename) as file_object:
for line in file_object:
lines = file_object.readlines()
for line in lines:
print(line.strip())
lines列表中的每個元素就是file_object的每一行內(nèi)容。
filename = 'pi_millon_digits.txt'
with open(filename) as file_object:
lines = file_object.readlines()
pi_string = ''
for line in lines:
pi_string += line.strip()
print(pi_string[:52] + "...")
圓周率是否包含你的生日
filename = 'pi_millon_digits.txt'
with open(filename) as file_object:
lines = file_object.readlines()
pi_string = ''
for line in lines:
pi_string += line.strip()
birthday = input("Enter your birthday, in the form mmddyy:")
if birthday in pi_string:
print("Your birthday appears in the first millon digits of pi!")
else:
print("Your birthday does not appears in the first millon digits of pi!")
寫入文件
filename = 'programming.txt'
with open(filename,'w') as file_object:
file_object.write("I love programming.")
調(diào)用open時炫贤,提供了兩個參數(shù)溅固,第一個參數(shù)是要打開的文件的名稱,第二個參數(shù)'w'告訴Python照激,我們要以寫入的方式打開文件发魄。
打開文件有幾種模式
w-寫入模式
r-只讀模式
a-附加模式
r+-讀取和寫入模式
如果省略模式實參,那Python默認以只讀打開
如果要寫入的文件不存在俩垃,函數(shù)open()自動創(chuàng)建它励幼。以'w'模式打開文件要小心,如果文件以及存在口柳,Python將返回對象前清空該文件苹粟。
Python只能將字符串寫入文本文件。要將數(shù)值數(shù)據(jù)存儲到文本文件跃闹,必須先試用str()函數(shù)將其轉(zhuǎn)換為字符串格式嵌削。
寫入多行
file_object.write("I love programming.\n")
file_object.write("I love creating new game.\n")
如果不加換行符毛好,則會連成一行
附加到文件
如果你想給文件添加內(nèi)容,而不是覆蓋原有的內(nèi)容苛秕,可以附加模式打開文件肌访。你以附加模式打開文件時,Python不會再返回文件對象前清空文件艇劫,而你寫入到文件的行都將添加到文件末尾吼驶。如果你指定的文件不存在,Python將為你創(chuàng)建一個空文件店煞。
異常
filename = 'alice.txt'
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()
num_words = len(words)
print("The file " + filename + " has about " + str(num_words) + " words.")
存儲數(shù)據(jù)
使用json.dump()和json.load()
函數(shù)json.dump()接受兩個實參蟹演,要存儲的數(shù)據(jù)以及可用于存儲數(shù)據(jù)的文件對象。
import json
filename = 'username.json'
try:
with open(filename) as f_obj:
username = json.load(f_obj)
except: FileNotFoundError:
username = input("What is your name?")
with open(filename,'w') as f_obj:
json.dump(username, f_obj)
print("We'll remeber you when you come back, " + username + "!")
else:
print("Welcome back, " + username + "!")
第十一章 測試代碼
name_function.py
def get_formatted_name(first_name, last_name):
full_name = first_name + ' ' + last_name
return full_name.title()
names.py
from name_function import get_formatted
print("Enter 'q' at any time to quit.")
while True:
first = input("\nPlease give me a first name:")
if first == 'q':
break
last = input("\nPlease give me a last name:")
if last == 'q':
break
formatted_name = get_formatted_name(first,last)
print("\tNeatly formatted name:" + formatted_name + '.')
單元測試
test_name_function.py
import unittest
from name_function import get_formatted_name
class NameTestCase(unittest.TestCase):
"""測試name_function.py"""
def test_first_last_name(self):
formatted_name = get_formatted_name('janis', 'joplin')
self.assertEqual(formatted_name, 'Janis Joplin')
unittest.main()
首先我們創(chuàng)建了一個名為NameTestCase的類顷蟀,用于包含一系列針對get_formatted_name()的單元測試酒请。你可以隨便給這個類命名,但最好讓它看起來與測試的函數(shù)相關(guān)鸣个,并包含Test字樣羞反。這個類必須繼承unittest.TestCase類,這樣Python才知道如何運行你編寫的測試毛萌。
NameTestCase只包含一個方法苟弛,用于測試get_formatted_name()的一個方面。我們將這個方法命名為test_first_last_name()阁将。
我們運行test_name_function.py時膏秫,所有以test_打頭的方法都將自動運行。
方法里做盅,我們使用了unittest類最常用的功能之一:一個斷言方法缤削。斷言方法用來合適得到的結(jié)果是否與期望的結(jié)果一致。
unittest斷言方法
方法 | 用途 |
---|---|
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中 |
測試類
survey.py
class AnonymousSurvey():
"""收集匿名調(diào)查問卷答案"""
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)
測試AnonymousSurvey類
test_survey.py
import unittest
from survey import AnonymousSurvey
class TestAnonymousSurvey(unittest.TestCase):
"""針對AnonymousSurvey類的測試"""
def setUp(self):
question = "What language did you first leanr to speak?"
self.my_survey = AnonymousSurvey(question)
self.responses = ['English', 'Spanish', 'Mandarin']
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_response(self):
for response in self.responses:
self.my_survey.store_response(response)
for response in self.responses:
self.assertIn(response, self.my_survey.responses)
unittest.main()
方法setUp()
在前面的測試代碼中吹榴,我們在測試方法中都單獨創(chuàng)建了AnonymousSurvey的實例亭敢。
有沒有辦法進行優(yōu)化?
可以使用setUp(),讓我們只需創(chuàng)建這些對象一次图筹,并在每個測試方法中運用它們帅刀。
如果你在TestCase類中包含方法setUp(),Python將先運行它远剩,再運行各個以test_打頭的方法扣溺。
import unittest
from survery import AnonymousSurvey
class TestAnonymousSurvey(unittest.TestCase):
"""針對AnonymousSurvey類的測試"""
def setUp(self):
question = "What language did you first leanr to speak?"
self.survey = AnonymousSurvey(question)
self.responses = ['English', 'Spanish', 'Mandarin']
def test_store_single_response(self):
my_survey.store_response(self.responses[0])
self.assertIn(self.responses[0], my_survey.response)
def test_store_three_response(self):
for response in responses:
my_survey.store_response(response)
for response in responses:
self.assertIn(response, my_survey.responses)
unittest.main()