Python Web工程師面試總結(二)- Python基礎
上篇籠統地聊了整個知識框架,這一篇會重點談談其中的常問的 Python 基礎知識部分。
題目:
- 談談 Python2 與 Python3 的差別
- Python 中的單下劃線與雙下劃線分別指什麼
- 聊聊 Python 中的可變物件與不可變物件
- Python 中的迭代器與生成器是什麼
- Python 中的裝飾器是什麼? 有什麼用
- Lambda 表示式是什麼?
- 簡述庫包模組之間的關係
- 如何管理 Python 環境, 為什麼要管理?
- Python 中的 with 關鍵字是什麼?
- *args 與 **kwargs 引數分別是什麼含義?
- is 與 == 的區別
答案:
1. 談談 Python2 與 Python3 的差別
- print 語句更換為 print() 函式
- 所有字串預設均為 Unicode, 不再區分 ASCII 與 Unicode 文字
- 除法運算中兩個整數相除可以直接得到浮點數, // 為整除符號不變
Python 2.7.15 (default, May1 2018, 05:55:50) [GCC 7.3.0] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> 1/2 0 >>> 1 // 2 0 >>> 1.0 / 2 0.5
Python 3.6.5 (default, May 11 2018, 13:30:17) [GCC 7.3.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> 1 / 2 0.5 >>> 1 // 2 0 >>> 1.0 // 2 0.0
- 合併 raw_input() 與 input() 為 input(), raw_input() 刪除, 可以直接輸入數字和文字, 不再區分
- 合併 xrange() 特性到 range(), 移除 xrange()
- dict 的 .keys() .values()函式均返回迭代器而非列表, range, zip 也將返回迭代器, 同樣的還有 map(), filter()
- 不等運算子 <> 被移除
- 八進位制表示式示例由 0777 變為 0o777
2. Python 中的單下劃線與雙下劃線分別指什麼
__name__ _name __name _
n = 42 for _ in range(n): do_something()
3. 聊聊 Python 中的可變物件與不可變物件
- 不可變物件 ,該物件所指向的記憶體中的值不能被改變 。當改變某個變數時候,由於其所指的值不能被改變,相當於把原來的值複製一份後再改變,這會開闢一個新的地址,變數再指向這個新的地址。(也就是說改變了就等於申請了一塊新的空間)
- 可變物件 ,該物件所指向的記憶體中的值可以被改變 。變數(準確的說是引用)改變後,實際上是其所指的值直接發生改變,並沒有發生複製行為,也沒有開闢新的出地址,通俗點說就是原地改變。
最簡單的例子就是看變數的 id
Python 3.6.5 (default, May 11 2018, 13:30:17) [GCC 7.3.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> # string is not constant >>> a = 'hhh' >>> id1 = id(a) >>> a += 'lll' >>> a 'hhhlll' >>> id2 = id(a) >>> id1 == id2 False >>> # list is inconstant >>> b = [1,2,3] >>> id3 = id(b) >>> b.append(4) >>> id4 = id(b) >>> id3 == id4
4. Python 中的迭代器與生成器是什麼
**注意是生成器不是生成式. **
生成器:如果列表元素可以按照某種演算法推算出來,那麼就可以在後續迴圈中不斷推算得出元素, 不必建立完整的list,從而節省大量的記憶體. 在Python中,這種一邊迴圈一邊計算的機制,稱為生成器:generator. 生成器是迭代器的一種. 生成器一次只能產生一個值, 而不是整個列表返回.
建立一個generator,有很多種方法,第一種方法很簡單,只有把一個列表生成式的 [] 中括號改為 () 小括號,就建立一個generator
>>> li = [x for x in range(5)] >>> li [0, 1, 2, 3, 4] >>> gen = (x for x in range(5)) >>> gen <generator object <genexpr> at 0x7f42b26b3a98> >>> gen.__next__() 0 >>> gen.__next__() 1 >>> next(gen) 2 >>> next(gen) 3 >>> next(gen) 4 >>> next(gen) Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration >>> gen = (x for x in range(5)) >>> for i in gen: ...print(i) ... 0 1 2 3 4
迭代器:
迭代器與可迭代物件是被包含的關係,可迭代物件不一定是迭代器 .
- 凡是可作用於for 迴圈 的物件都是Iterable 型別;
-
凡是可作用於next()
函式的物件都是Iterator
型別,它們表示一個惰性計算的序列;(
惰性計算的一個例子是
if a and b
當 a 為 False, 則 b 不再計算, 結果肯定是 False, 用在迭代器則是如果你不訪問該值, 則不取出該值 ) - 集合資料型別如list、dict、str等是Iterable但不是Iterator,不過可以通過iter()函式獲得一個Iterator物件。
5. Python 中的裝飾器是什麼? 有什麼用
裝飾器本質上是一個Python函式,它可以讓其它函式在不作任何變動的情況下增加額外功能(也就是說, 是可以繼承的),裝飾器的返回值也是一個函式物件。它經常用於有切面需求的場景。比如:插入日誌、效能測試、事務處理、快取、許可權校驗等 。有了裝飾器我們就可以抽離出大量的與函式功能無關的雷同程式碼進行重用。
6. Lambda 表示式是什麼?
傳入函式時,有些時候,不需要顯式地定義函式,直接傳入匿名函式更方便。匿名函式有個限制,就是隻能有一個表示式,不用寫return,返回值就是該表示式的結果。
例如lambda x: x * x
實際上就是:
def f(x): return x * x
關鍵字lambda表示匿名函式,冒號前面的x表示函式引數。
用匿名函式有個好處,因為函式沒有名字,不必擔心函式名衝突。此外,匿名函式也是一個函式物件,也可以把匿名函式賦值給一個變數,再利用變數來呼叫該函式, 同時匿名函式既然是一個物件, 也可以作為返回值:
>>> f = lambda x: x*x >>> f(5) 25 >>> def test(x, y): ...return lambda: x*x + y ... >>> test(5, 1) <function test.<locals>.<lambda> at 0x7f42b26a5ae8>
7. 簡述庫包模組之間的關係
Python 中的庫是指具有相關功能模組的集合。一個庫通常由多個模組. 如sys
是一個和系統操作相關的標準庫.
包是模組檔案的打包, 包(Package)下面會有一個__init__.py
的檔案. 若有子目錄且子目錄下也有__init__.py
的檔案, 則稱子目錄為子包.
模組是一個個.py檔案, 裡面包含函式和變數等.
8. 如何管理 Python 環境, 為什麼要管理?
使用 Virtualenv, anaconda 等包管理工具進行管理. 管理的原因是為了在系統上開發多個專案時不會產生庫和包的汙染, 也可以讓 Python 的不同版本共存. 不同專案使用不同的虛擬環境, 在專案最後匯出所需的包的時候也不會產生包的並集, 所需多少就是多少.
9.Python 中的 with 關鍵字是什麼?
with 是與異常處理 相關的功能, with 語句適用於對資源進行訪問 的場合,確保不管使用過程中是否發生異常都會執行必要的“清理”操作,釋放資源,比如檔案使用後自動關閉 、執行緒中鎖的自動獲取和釋放 等。
格式如下:
with context_expression [as target(s)]: with-body
訪問語句中的with-body
前會呼叫__enter__()
結束時呼叫__exit__()
, 無論是否有異常,__exit__()
都會做好收尾工具, 不需要再try catch
10.*args
與**kwargs
引數分別是什麼含義?
如果我們不確
定往一個函式中傳入多少引數
,或者我們希望以元組(tuple)
或者列表(list)
的形式傳引數的時候,我們可以使用*args
(單星號)。如果我們不知道往函式中傳遞多少個關鍵詞引數
或者想傳入字典
的值作為關鍵詞引數的時候我們可以使用**kwargs
(雙星號)
11. is 與 == 的區別
前面提到用 id 是否相等來判斷變數是否可變, 我們用了==
符號, 如果直接用is
關鍵詞, 那麼不用獲得 id 就可以判斷兩個是否是同一個變數.
下面給出一個例子, a 先賦值給 c, c 成為 a 的引用, 分別拼接相同的字串, 此時二者仍相等, 但是此時a is not c
>>> a = 'hhh' >>> c = a >>> a += 'lll' >>> c += 'lll' >>> a == c True >>> a is c False
從這裡可以知道is
判斷的是是否指向同一個記憶體空間,==
判斷的是純粹的值是否相等.
Reference:
公眾號: 程式設計師的碎碎念