第五章:條件、迴圈以及其他語句(上)
第五章 條件、迴圈以及其他語句
5.1 再談print和import
隨著我們對於Python的認知越來越多,很多我們以前不清楚的東西慢慢都需要了解,下面在談談print和import等我們所不知道的一些地方。原來的print在python2.7中是一個語句,但python3.5中,print由一個語句,轉變成一個函式,注意,這個轉變很重要。可能比以前有用很多,而且還可能簡潔很多。
提示 在這裡,我們談及了使用模板logging去寫入日誌比用print有用,但具體什麼用,大家有個大致瞭解,以後在學習中遇到去處理即可。
5.1.1 列印多個引數
print可用於列印一個表示式,記住有兩種情況的存在,如果你在裡面輸入的是字串,就直接打印出來字串,第二種情況就是把你輸入的非字串直接轉換成字串進行列印。而且,你需要注意的地方是,你可以列印多個表示式,條件是用逗號進行分隔它們:
print('age:',42)
看看出來的結果,就能發現,在引數之間插入了一個空格字元。
age: 42
在此,作者提出我們需要合併文字和變數值的時候,而又不想使用字串格式設定功能的時候,這很有幫助。對於這點我的理解就是作者已經脫離了原本的print概念,而是提出了關於合併文字和變數值的一種做法,就是中間加入一個空格,但具體用在什麼地方,我覺得還有待進一步的瞭解。
在下面作者又提出了一些有用的技巧,我現在為大家一一的介紹:
首先,我來介紹第一種的技巧:
name='Gumby' salutation='Mr.' greeting='Hello,' print(greeting,salutation,name)
從而,會得到這樣的結果:
Hello, Mr. Gumby
作者在這裡就進行了思考,如果變數greeting不包含逗號,那麼如何處理,具體如下:
print(greeting+',',salutation,name)
這樣的結果就能變成魚上述答案一直的結果。
其次,就是第二種情況,如果我需要在每個我輸入的表示式之間自己去新增分隔符,注意前面我們看看作者在上面的時候是幹什麼,是直接預設為空格,而現在我們有辦法通過自己的需求進行設定:
print('I','wish','to','register','a','complaint',sep='_')
從而,得到答案即為:
I_wish_to_register_a_complaint
5.1.2 匯入時重新命名
從 模板匯入,通常有四種情況,通常使用:
import somemodule
或使用
from somemodule import somefunctuon
或
import somemodule import somefunction,anotherfunction,yetanotherfunction
或
from somemodule import *
匯入模板裡面所有的東西的時候,用的是最後一個方式。如果你需要使用兩個模板,而且他們都包含例如函式open之類的同名函式,這個時候肯定會出問題,那麼此處你應該使用第一種方式去處理,當然你在具體使用的時候也需要注意要用的方法與方法:
module1.open(...)
module2.open(...)
作者在這裡也提出了一些其他的方法:在語句末尾新增as子句並指定別名。下面是一個匯入整個模組並給它指定別名的例子:
import math as foobar print(foobar.sqrt(4))
從而,得到答案就是:
2.0
而讓偶感覺舒服的一點就是,作者在函式部分的處理,也能像剛剛上面的例子一樣,命名別名,然後,匯入:
from module1 import open as open1
from module2 import open as open2
5.2 賦值魔法
這裡面也有很多我們需要去處理的細節。
5.2.1序列解包
賦值語句常常是給變數和資料結構的一部分(如列表的元素和切片,或者字典項)賦值,還有其他的賦值,例如,可同時給多個變數賦值,這個是以前沒有的。當然,也可利用這種方式進行交換多個變數的值,這個部分總感覺容易用錯,儘量不要用:
x ,y ,z=1,2,3 print(x,y,z) x,y=y,x print(x,y,z)
從而,我們來看看它的輸出結果:
1 2 3 2 1 3
這裡面其實就是在運用資料結構和演算法設計的一些資料結構,文章中把這種操作稱為序列解包(或可迭代物件解包):將一個序列(或其他可迭代物件)解包,並將得到的值儲存到一系列變數中。(意思就是可迭代物件(不清楚就去檢視資料結構或者演算法設計)或者序列分配給變數,說白了,就是一個個讀取,然後分配給變數)下面作者還舉了一個具體的例子:
values=1,2,3 print(values) x,y,z=values print(x)
這裡可以看出來得到的解包最後給了x,y,z三個變數,並最後輸出了x,這個就是典型的序列解包,當然,你需要注意的一點就是,變數的數量要和你解包的數值一一對應,否則內容就會報錯。而且,注意到這裡的程式碼的第一行,直接給一個變數賦了三個值,結果就變成了一個元組;當然作者在這裡提出來的在使用元組(或其他序列或可迭代物件)的函式或方法的時候很有用,具體怎麼用,還是有待進一步的考究的。本文在後面也提出了在字典的一種情況,就是字典隨機獲取(或刪除)一個鍵-值對,可使用方法popitem,它隨機獲取一個鍵-值對然後刪除並且會以元組的方式進行返回。所以能進行上述的操作,但不能用pop這個方法,因為,不指定的時候刪除最後一個,指定的時候刪除對應的位置。但不會返回任何東西。
scoundre1={'name':'Robin','girlfriend':'Marion'} key,values=scoundre1.popitem() print(key,values)
對應的結果如下:
girlfriend Marion
這裡作者也提醒了我們,要解包的序列包含的元素個數必須與你等號左邊列出的目標個數相同,否則Python將引發異常。舉個例子:
x,y,z=1,2
x,y,z=1,2,3,4
兩種情況報錯的內容大致都是一致的:
x,y,z=1,2 ValueError: not enough values to unpack (expected 3, got 2)
x,y,z=1,2,3,4
ValueError: too many values to unpack (expected 3)
注意,為了彌補上述的不足,這裡提出了一個很有用的解決方法,就是使用星號運算子(*) 來蒐集多餘的值,這樣無需保證值得數量和變數的數量是一樣多的,下面具體舉個例子可以看出:
a,b, *rest=[1,2,3,4] print(a,b,rest)
從而,我們就得到這樣的答案:
1 2 [3, 4]
當然,帶*的位置我們也能做出適當的調整,系統也會做出調整,如下一個示例:
name='Albus Percival Wulfric Brian Dumbledore' first,*middle,last=name.split() print(first,middle,last)
從而得到合適的答案:
Albus ['Percival', 'Wulfric', 'Brian'] Dumbledore
賦值語句的右側可以是任何型別的序列,但帶星號的變數最終包含的總是一個列表。在變數和值相等的情況下不會改變這種情況:
name='Albus Percival Wulfric ' first,*middle,last=name.split() print(first,middle,last)
當然,結果與上述是一致的:
Albus ['Percival'] Wulfric
5.2.2 鏈式賦值
鏈式賦值是一種快捷方式,用於將多個變數關聯到同一個值,但只涉及到一個值,這很重要。
x=y=somefunction()
與上述程式碼一致的程式碼:
y=somefunction()
x=y
但與下面不等價:
x=somefunction()
y=somefunction()
5.2.3 增強賦值
其實在C/C++裡面也很常見,x=x+1改變為x+=1,這個語句很常見,就叫做增強賦值。適用於所有的標準運算子,如*、/、%等。
增強賦值也可適用於其他資料型別(只要在雙目運算子可以做到的這裡都能做到,什麼是雙目,比如++等)
fnord='foo' fnord+='bar' print(fnord) fnord*=2 print(fnord)
從而,有下面的結果:
foobar
foobarfoobar
5.3 程式碼塊:縮排的樂趣
程式碼塊不是語句,但你要理解這個內容,下面的東西才能講下去:
程式碼塊是一組語句的組合,可滿足條件時執行(if)的語句、可執行多次的(迴圈語句),等等。程式碼塊通過縮排(也就是加空格)來建立。說白了,C/C++等語言原來都是有括號{ }來保證其裡面的內容,現在只是沒有了{ },取而代之的縮排而已,記住每級縮排4個空格就可以了。具體,後面看看你就知道怎麼用,在這不在贅述。