程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

Python 快速入門(第3版)8-10章 讀書筆記

編輯:Python

《Python 快速入門(第3版)》娜奧米·賽德

8.2 if-elif-else語句

Python中沒有提供case語句。在大多數其它語言采用case或switch語句的場合,Python可以用串聯的if...elif...elif...else結構來應對。如果遇到極少數棘手的場合,通常可用函數字典來解決

def do_a_stuff():
#process a
def do_b_stuff():
#process b
def do_c_stuff():
#process c
func_dict = {'a' : do_a_stuff,
'b' : do_b_stuff,
'c' : do_c_stuff }
x = 'a'
func_dict[x]()

例如,

def do_a_stuff(a,b):
return a+b
def do_b_stuff(a,b):
return a-b
def do_c_stuff(a,b):
return a*b
func_dict = {'a' : do_a_stuff,
'b' : do_b_stuff,
'c' : do_c_stuff }
x = 'a'
y = func_dict[x](333,555)
print(y) #輸出888

8.3.1 range函數

對於給出的數字n,range(n)會返回0、1、2、……、n-2、n-1。因此,將列表長度(調用len函數)傳入就會產生列表元素索引的序列。

>>> range(10)
range(0, 10)
>>> type(range(10))
<class 'range'>
>>> list(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>

如果有兩個數值參數,則第一個是結果序列的起始值,第二個是結果序列的結束值(不含)。

range函數的第三個可選參數,以便給出計數時的步進值。

>>> list(range(2,8))
[2, 3, 4, 5, 6, 7]
>>> list(range(2,8,3))
[2, 5]
>>>

8.3.4 for循環和元組拆包

下述代碼在for關鍵字之後緊跟著用到了元組x,y,而不是平常的單個變量。

>>> somelist = [(1, 2), (3, 7), (9, 5)]
>>> result = 0
>>> for x, y in somelist:
... result = result + (x * y)
...
>>> result
68
>>>

8.3.5 enumerate函數
enumerate函數返回的是元組(索引,數據項)
通過組合使用元組拆包和enumerate函數,可以實現同時對數據項及其索引進行循環遍歷。

>>> x = [2, -3, 5, -7, -11]
>>> enumerate(x)
<enumerate object at 0x7f752b4ed090>
>>> list(enumerate(x))
[(0, 2), (1, -3), (2, 5), (3, -7), (4, -11)]
>>>
>>> for i,n in enumerate(x):
... if n < 0:
... print("Found a negative number at index:", i)
...
Found a negative number at index: 1
Found a negative number at index: 3
Found a negative number at index: 4
>>>

8.3.5 zip函數

zip函數可以從一個或多個可迭代對象中逐一讀取對應元素,並合並為元組,直至長度最短的那個可迭代對象讀取完畢

>>> a = [1, 2, 3, 4]
>>> b = ['a', 'b', 'c', 'd', 'e', 'f']
>>> z = zip(a,b)
>>> list(z)
[(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd')]
>>>

8.4 列表和字典推導式

列表推導式的用法如下:
​​new_list = [expression1 for variable in old_list if expression2]

字典推導式的用法如下:
​​new_dict = {expression1:expression2 for variable in list if expression3}​​

生成器表達式
注意:除方括號的變化之外,生成器表達式還不返回列表。生成器表達式返回的是生成器對象,可用作for循環中的迭代器,這與range()函數的用途非常類似。
使用生成器表達式的優點是,不會在內存中生成整個列表。因此可生成任意大小的值序列,內存開銷也很小。

動手題:推導式為了去除列表x中的負數,該用什麼列表推導式來處理列表?
創建能返回1到100之間奇數的生成器。提示:奇數除以2後會有余數,余數可以用%2操作得到。
編寫代碼創建一個字典,鍵為11到15之間的數字,值為鍵的立方。

1.
>>> x_nonegative = [ a for a in x if a >=0 ]
>>> x_nonegative
[11, 666, 5, 223, 886]
>>>
>>>
>>> x_nonegative = [ x for x in x if x >=0 ]
>>> x_nonegative
[11, 666, 5, 223, 886]
>>>
2.
>>> gen = (i for i in list(range(100)) if i % 2 !=0)
>>> next(gen)
1
>>> next(gen)
3
>>> next(gen)
5
>>> next(gen)
7
>>>
3.
>>> { key:key**3 for key in list(range(11,16))}
{11: 1331, 12: 1728, 13: 2197, 14: 2744, 15: 3375}
>>>

8.6 布爾值和布爾表達式

操作符and和or將會返回對象
and操作符要麼返回第一個為False的對象(表達式的計算結果),要麼返回最後一個對象。
or操作符要麼返回第一個為True的對象,要麼返回最後一個對象。

大多數情況下,用到的都是==和!=,而不是is和is not。is和is not用來判斷操作對象是否為同一個對象

9.4 局部變量、非局部變量和全局變量
nonlocal語句與global語句類似,它會讓標識符引用最近的閉合作用域(enclosing scope)中已綁定的變量。

例:

如果想對函數之外的變量賦值,就必須將其顯式聲明為nonlocal或global。但如果只是要訪問函數外的變量,則不需要將其聲明為nonlocal或global。

9.6 lambda表達式

​​lambda parameter1, parameter2, . . .: expression​​

>>> deg_C2K = lambda deg_C: 273.15 + deg_C
>>> deg_C2K(32)
305.15
>>>

9.8 裝飾器

def decorate(func):
print("in decorate function, decorating", func.__name__)
def wrapper_func(*args):
print("Executing", func.__name__)
return func(*args)
return wrapper_func
def myfunction(parameter):
print(parameter)
myfunction = decorate(myfunction)
myfunction("hello")

輸出結果:
in decorate function, decorating myfunction
Executing myfunction
hello

裝飾器(decorator)就是上述過程的語法糖(syntactic sugar),只增加一行代碼就可以將一個函數包裝到另一個函數中去。效果與上述代碼相同。

裝飾器由兩部分組成:先定義用於包裝或“裝飾”其他函數的裝飾器函數;然後立即在被包裝函數的定義前面,加上“@”和裝飾器函數名。

def decorate(func):
print("in decorate function, decorating", func.__name__)
def wrapper_func(*args):
print("Executing", func.__name__)
return func(*args)
return wrapper_func
@decorate
def myfunction(parameter):
print(parameter)
myfunction("hello")

輸出結果:
in decorate function, decorating myfunction
Executing myfunction
hello

交互模式

>>> def decorate(func):
... print("in decorate function, decorating", func.__name__)
... def wrapper_func(*args):
... print("Executing", func.__name__)
... return func(*args)
... return wrapper_func
...
>>> @decorate
... def myfunction(parameter):
... print(parameter)
...
in decorate function, decorating myfunction
>>>
>>> myfunction("hello")
Executing myfunction
hello
>>>

10.2 編寫第一個模塊

mymath.py內容如下

"""mymath - our example math module"""
pi = 3.14159
def area(r):
global pi
return(pi * r * r)
>>> import mymath
>>> pi
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'pi' is not defined
>>>
>>> mymath.pi
3.14159
>>>

如果修改了磁盤中的模塊文件,那麼再次輸入import命令並不會重新加載模塊,這時要用到模塊importlib的reload函數才可以。importlib模塊為訪問模塊導入的後台機制提供了一個接口:

>>> mymath.pi
3.14159
>>> import mymath, importlib
>>> importlib.reload(mymath)
<module 'mymath' from '/root/mymath.py'>
>>> mymath.pi
3.14
>>>

當模塊被重新加載(或第一次導入)時,其所有的代碼都會被解析一遍。如果發現錯誤,則會引發語法異常。反之,如果一切正常就會創建包含Python字節碼的.pyc文件,如mymath.pyc。

10.4 模塊搜索路徑
sys.path是Python的搜索模塊的路徑集,是一個列表

>>> sys.path
['', '/usr/local/python3/lib/python39.zip', '/usr/local/python3/lib/python3.9', '/usr/local/python3/lib/python3.9/lib-dynload', '/usr/local/python3/lib/python3.9/site-packages']
>>>

說明:sys.path的第一個元素為"",這會告知Python要在當前目錄中查找模塊。

10.5 模塊內部私有名稱

模塊中下劃線開頭的標識符不能用from module import *導入。用前導下劃線表示私有名稱的約定,整個Python中都在使用,而不僅用在模塊中。

例如 modtest.py內容如下

def f(x):
return x
def _g(x):
return x
a = 4
_b = 2

啟動一個交互式會話測試

>>> from modtest import *
>>> f(3)
3
>>> _g(3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name '_g' is not defined
>>>

注意:只有from <module> import *才會有這種行為。以下方式操作還是可以訪問到_g和_b的:

啟動一個交互式會話測試

>>> import modtest
>>> modtest._g(3)
3
>>> modtest._b
2
>>>

啟動一個交互式會話測試

>>> from modtest import _g,_b
>>> _g(3)
3
>>> _b
2
>>>

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved