python 面試題匯總 基礎篇答案整理(80 題)
面試題匯總
第一部分 Python 基礎篇(80 題)
-
為什么學習 Python?
語言本身簡潔,優美,功能超級強大 跨平臺 是未來科技著重發展的方向, 例如機器學習、 深度學習、人工智能 有廣闊的前景 -
通過什么途徑學習的 Python?
系統的視頻教程,官方文檔,和其他網站教程文檔(如 runoob),開源代碼(如github、gitee) -
Python 和 Java、PHP、C、C#、C++ 等其他語言的對比?
python Java 解釋型語言 c c++ 為編譯型語言 python java c++ 為面向對象語言 PHP 開源的腳本語言 只適用于網頁編程,而Python適合于各個領域。 1.難易度而言。python遠遠簡單于java、C#。 2.開發速度。Python遠優于java、C# 3.運行速度。java、C#遠優于標準python,pypy和cython可以追趕java,但是兩者都沒有成熟到可以做項目的程度。 4.可用資源。java、C#資源豐富,python很少很少,尤其是中文資源。 5.穩定程度。python3和2不兼容,造成了一定程度上的混亂以及大批類庫失效。java、C#由于有企業在背后支持所以穩定的多。 6.是否開源。python從開始就是完全開源的。Java由sun開發,但現在有GUN的Openjdk可用,C#也在逐漸開源。 7.編譯還是解釋。都是解釋型。 -
簡述解釋型和編譯型編程語言?
解釋型語言 便翻譯邊執行,執行速度慢、效率低;依賴解釋器、跨平臺性好。 編譯型編程語言,把源程序全部都編譯成機器語言,并保存成二進制文件執行。速度快、效率高;依賴編譯器、跨平臺性差些。 -
Python 解釋器種類以及特點?
CPython 當 從Python官方網站下載并安裝好Python2.7后,就直接獲得了一個官方版本的解釋器:Cpython,這個解釋器是用C語言開發的,所以叫 CPython,在命名行下運行python,就是啟動CPython解釋器,CPython是使用最廣的Python解釋器。 /headIPython IPython是基于CPython之上的一個交互式解釋器,也就是說,IPython只是在交互方式上有所增強,但是執行Python代碼的功能和CPython是完全一樣的,好比很多國產瀏覽器雖然外觀不同,但內核其實是調用了IE。 PyPy PyPy是另一個Python解釋器,它的目標是執行速度,PyPy采用JIT技術,對Python代碼進行動態編譯,所以可以顯著提高Python代碼的執行速度。 Jython Jython是運行在Java平臺上的Python解釋器,可以直接把Python代碼編譯成Java字節碼執行。 IronPython IronPython和Jython類似,只不過IronPython是運行在微軟.Net平臺上的Python解釋器,可以直接把Python代碼編譯成.Net的字節碼。 在Python的解釋器中,使用廣泛的是CPython,對于Python的編譯,除了可以采用以上解釋器進行編譯外,技術高超的開發者還可以按照自己的需求自行編寫Python解釋器來執行Python代碼,十分的方便! -
位和字節的關系?
一個字節等于8位 -
b、B、KB、MB、GB 的關系?
8 b = 1 B 1024 B = 1 KB 1024KB = 1 MB 1024 MB = 1 GB -
請至少列舉 5 個
PEP8規范(越多越好)。1. 導入模塊: 導入不同模塊單獨起一行, 同模塊的類,可多個導入;不使用 星號導入所有 2. 同一行不以分號分隔寫多個語句 3. 代碼間隔:賦值或運算操作符,兩邊空, 關鍵字傳參不需要空格;閉合符號相鄰不留空;內部模塊和第三方模塊空一行 ,導入操作和代碼空兩行;類之間空一行, 函數或方法之間空一行 4. 變量命名: 駝峰命名法和下劃線命名, 類名首字母大寫, 函數名首字母小寫 5. 縮進使用四個空格, 不與制表符混用 -
通過代碼實現如下轉換:
二進制轉換成十進制:v = “0b1111011”
十進制轉換成二進制:v = 18
八進制轉換成十進制:v = “011”
十進制轉換成八進制:v = 30
十六進制轉換成十進制:v = “0x12”
十進制轉換成十六進制:v = 87v = "0b1111011" print('二進制 "0b1111011" 轉換十進制等于:',int(v, 2)) v = 18 print("整數 18 轉二進制等于:", bin(v)) v = "011" print('八進制 "011" 轉換十進制等于:',int(v, 8)) v = 30 print("整數 30 轉換八進制等于:", oct(v)) v = "0x12" print('十六進制 "0x12" 轉換十進制等于:',int(v, 16)) v = 87 print("整數 18 轉十六進制等于:", hex(v)) -
請編寫一個函數實現將 IP 地址轉換成一個整數。
如 10.3.9.12 轉換規則為: 10 00001010 3 00000011 9 00001001 12 00001100
再將以上二進制拼接起來計算十進制結果:00001010 00000011 00001001 00001100 = ?ip = "10.3.9.12" ips = ip.split('.') # 遍歷對每個ip字段轉換二進制以"0"補全八位 res = int("".join([bin(int(d))[2:].rjust(8, '0') for d in ips]), 2) print(res) -
python 遞歸的最大層數? 遞歸的最大深度默認是1000 層
實際運用: python2 都可以遞歸計算到999,python3只能遞歸到998import sys print(sys.getrecursionlimit()) # 獲取默認遞歸深度sys.setrecursionlimit(自定義深度) # 手動設置遞歸深度## 遞歸深度測試 def fn(n): if n==1: return 1 else: return fn(n-1) fn(1000) # 出錯 fn(998) # 輸出1 -
求結果:
v1 = 1 or 3 # 結果 1 v2 = 1 and 3 # 結果3 v3 = 0 and 2 and 1 # 返回0 v4 = 0 and 2 or 1 # 返回1 v5 = 0 and 2 or 1 or 4 # 返回1 v6 = 0 or Flase and 1 # 返回 Flase擴展1: or 返回第一個True的值,沒有返回最后一個值, and 返回第一個False值,沒有返回最后的正確值,因為or優先級最低發現正確的值就不再判斷, and發現錯誤的值就不做and的判斷,優先級: not > and > or 擴展2: 值為False的值: 空序列類型: [] () {} ’’ "" 空數值類型: 0 -0 0j 0.0 空值:None -
ascii、unicode、utf-8、gbk區別?ascii: 美國信息交換標準代碼(American Standard Code for Information Interchange),128個字符(0-127)的英文字符編碼一個字符對應一個字節 GBK: GB2312 是對 ASCII 的中文擴展GBK 包括了 GB2312 的所有內容,同時又增加了近 20000 個新的漢字(包括繁體字)和符號, GB18030 包含了GBK的所有,擴展了幾千個新的少數民族的字,通稱他們叫做 “DBCS”(Double Byte Charecter Set 雙字節字符集) 漢字一個字符 兩個字節 英文一個字符一個字節 unicode ISO包括了地球上所有文化、所有字母和符號的編碼!他們打算叫它 “Universal Multiple-Octet Coded Character Set”,簡稱 UCS。從 UNICODE 開始,無論是半角的英文字母,還是全角的漢字,都統一的 “一個字符”,即 “兩個字節” utf-8 使用最廣的一種unicode實現方式utf-8 面向傳輸的眾多 UTF(UCS Transfer Format)標準之一 每次傳輸8個位為了核對雙方對于高低位的認識是否是一致的,采用了一種很簡便的方法,就是在文本流的開始時向對方發送一個標志符——如果之后的文本是高位在位,那就發送 “FEFF”,反之,則發送 “FFFE”。 -
字節碼和機器碼的區別?
機器碼: 即原生碼: 即計算機可直接讀取的數據,可直接執行字節碼:通過編譯生成的程序和數據片段組成的二進制文件, 如.java通過編譯生成二進制.class文件 -
三元運算規則以及應用場景?
name = val1 if condition else val2用于 判斷條件 設置不同值 -
列舉 Python 2 和 Python 3 的區別?
xrange 和 range : 2.x xrange 返回生成器, range 返回列表, 3.x 中 拋棄xrange , range 返回生成器 xreadlines 和 readlines : 2.x xreadlines 返回生成器, readlines 返回列表, 3.x 中 拋棄xreadlines , readlines 返回生成器 print: 2.x 中print 為關鍵字 直接跟字符串 3.x中 print為函數 需添加括號包含字符串 raw_input()和input(): 2.x 中raw_input 輸入字符串,返回字符串 input 輸入數字,返回數字 3.x 中 只有input 輸入任何類型默認為字符串,返回字符串 編碼方式: 2.x中 文件默認編碼是ASCII,字符串默認也是ASCII 3.x 中 默認編碼是utf-8, 內存里(也就是字符串) 是編碼是unicode,即使聲明了某種編碼,在內存里還是unicode int 和 long: 2.x中 存在int和long 整型和長整型,int類型最大值不能超過sys.maxint 3.x 中只有int類型, 類似于2.x中的long 比較運算符: 2.x 支持<>作為!=的同義詞, 3.x 只支持!=, 不再支持<> 字典類方法的返回值: 2.x中 是列表。最常用方法有keys, items和values。3.x中,所有以上方法的返回值改為動態試圖 元類的使用: 2.x中,可以通過在類的聲明中定義metaclass參數,或者定義一個特殊的類級別(class-level)__metaclass__屬性,來創建元類。3.x中,__metaclass__屬性被取消了 -
用一行代碼實現數值交換:
a = 1b = 2a, b = b, a -
Python3 和 Python2 中
int和long的區別?2.x中 存在int和long 整型和長整型,int類型最大值不能超過sys.maxint 3.x 中只有int類型, 類似于2.x中的long -
xrange和range的區別?python2 中, xrange返回一個生成器, range返回一個列表. python3中, range返回一個生成器用于 迭代生成指定其實位置和步長的等差數列 -
文件操作時:
xreadlines和readlines的區別?差別類似xrange 和 rangepython2 中, xreadlines 返回一個生成器, readlines 返回一個列表 python3中, readlines 返回一個生成器用于 迭代逐行讀取文件文本 -
列舉布爾值為
False的常見值?布爾值為False: 空序列類型: [] () {} '' "" numbers類型: 0 -0 0j 0.0 空值:None -
字符串、列表、元組、字典每個常用的 5 個方法?
字符串: str join len title split upper lower rjust 元組: len tuple count index 列表:len pop index insert append extend sort 字典: items keys values getitem len -
lambda表達式格式以及應用場景?lambda 參數1: 表達式 , map() filter() -
pass的作用?未將來的實現代碼預留位置, 使沒有語句的函數不報錯。
-
*arg和**kwarg作用解包, *args 同時傳多個位置參數, ** kwarg 同時傳 多個關鍵字參數 -
is和==的區別is 比較內存地址ui否相同, ==比較值是否相同 -
簡述 Python 的深淺拷貝以及應用場景?
以列表嵌套列表為例 淺拷貝: 重新開辟空間存放元素地址,不包括嵌套列表內的元素 深拷貝:重新開辟空間 存放元素, 包括嵌套列表內的元素 即淺拷貝指僅僅拷貝數據集合的第一層數據,深拷貝指拷貝數據集合的所有層, 運用: 淺拷貝 copy模塊 copy函數, 切片, 深拷貝 copy模塊的 deepcopy函數 -
Python 垃圾回收機制?
python采用的是引用計數機制為主,標記-清除和分代收集兩種機制為輔的策略 python里每一個東西都是對象,它們的核心就是一個結構體:PyObject typedef struct_object { int ob_refcnt; struct_typeobject *ob_type; } PyObject; PyObject是每個對象必有的內容,其中ob_refcnt就是做為引用計數。當一個對象有新的引用時,它的ob_refcnt就會增加,當引用它的對象被刪除,它的ob_refcnt就會減少 #define Py_INCREF(op) ((op)->ob_refcnt++) //增加計數 #define Py_DECREF(op) \ //減少計數 if (--(op)->ob_refcnt != 0) \ ; \ else \ __Py_Dealloc((PyObject *)(op)) 當引用計數為0時,該對象生命就結束了。 引用計數機制的優點:簡單 實時性:一旦沒有引用,內存就直接釋放了。不用像其他機制等到特定時機。實時性還帶來一個好處:處理回收內存的時間分攤到了平時。 引用計數機制的缺點:維護引用計數消耗資源 ## 循環引用 # list1 = [] # list2 = [] # list1.append(list2) # list2.append(list1) list1與list2相互引用,如果不存在其他對象對它們的引用,list1與list2的引用計數也仍然為1,所占用的內存永遠無法被回收,這將是致命的。 對于如今的強大硬件,缺點1尚可接受,但是循環引用導致內存泄露,注定python還將引入新的回收機制。(標記清除和分代收集) -
Python 的可變類型和不可變類型?
可變類型:list, set, dict不可變類型: numbers, string ,tuple,frozenset -
求結果:
v = dict.fromkeys(['k1','k2'],[]) v['k1'].append(666) print(v) v['k1'] = 777 print(v)結果: {“k1”: 777, “k2”: [666]}說明:新建一個字典為{‘k1’:[], “k2”:[]} # 兩個字典的value 指向同一個空列表第一步在做了添加操作, 兩個表都填充上666第二步’k1’ 賦值, 重新指向 777 -
求結果:
def num(): return [Lambda x: i*x for i in range(4)] print([m(2) for m in num()])輸出結果: [6,6,6,6]lambda x : i*x 函數的命名空間只有x 只有函數運行時才會獲取 i 的值, 經過迭代最終的 i = 3函數改為 : [lambda x, i=i: x*i for i in range(4)] 這時的命名空間存在 x, i ,可以解決問題 -
列舉常見的內置函數?
dir()、 type()、 repr()、 exec()、 eval() getattr() isinstance() id() str() int() print() input() __import__() -
filter、map、reduce的作用?map是用同樣方法把所有數據都改成別的..字面意思是映射..比如把列表的每個數都換成其平方..
reduce是用某種方法依次把所有數據丟進去最后得到一個結果..字面意思是化簡..比如計算一個列表所有數的和的過程,就是維持一個部分和然后依次把每個數加進去..
filter是篩選出其中滿足某個條件的那些數據..字面意思是過濾..比如挑出列表中所有奇數..
map(lambda x:x*x,[0,1,2,3,4,5,6])
[0, 1, 4, 9, 16, 25, 36] # 操作獨立的元素 返回結果長度一致
reduce(lambda x,y:x+y,[0,1,2,3,4,5,6])
21 # 類似動態規劃 將之前的計算結果用于后續計算
filter(lambda x:x&1,[0,1,2,3,4,5,6])
[1, 3, 5] # 判斷篩選符合條件的元素
```
-
一行代碼實現
9*9乘法表print("\n".join([' '.join(["%dx%d=%d"%(x,y,x*y) for y in range(1,x+1)]) for x in range(1,10)])) -
如何安裝第三方模塊?以及用過哪些第三方模塊?
pip install 模塊名稱, 使用過flask django pymysql pyjwt pyredis pymongo pyjwt flask-sqlalchemy -
至少列舉 8 個常用模塊都有那些?
re sys time datetime json hashlib range md5 os requests urllib -
re的match和search區別?match 重起始位置開始匹配, search 從任意位置開始匹配 -
什么是正則的貪婪匹配?
.* 點匹配任何字符, *號表示0個或多個, 兩個連接使用, 會以盡可能多匹配符合的 -
求結果:
a. [i % 2 for i in range(10) ]b. ( i % 2 for i in range(10) )結果: a:一個列表 [0,1,0,1,0,1,0,1,0,1,] , b: 一個生成器 調用next() 方法逐個返回 -
求結果:
a. 1 or 2b. 1 and 2c. 1 <(2==2)d. 1 < 2 == 2結果: a : 1 , b: 2 , c. True , d:True(2==2) 結果為True python中 True 等于1 , False等于0 python 中的鏈式比較, 相當于 1<2 and 2==2 -
def func(a,b=[]) 這種寫法有什么坑?
形參指向的一個空列表,傳入參數a的操作 會疊加存入b中, b保存的元素會積累添加無法釋放 默認參數可以設置為None 可以解決 -
如何實現
"1,2,3"變成['1','2','3']?res = "1,2,3".split(",") -
如何實現
['1','2','3']變成[1,2,3]?[int(i) for i in ['1','2','3']] -
比較:
a = [1,2,3]和b = [(1),(2),(3) ]以及b = [(1,),(2,),(3,) ]的區別?a 和 第一個 b 一樣,是包含1,2,3的列表, 第二個是列表嵌套三個元組 元組元素只有一個時,需添加一個逗號, 否則 和沒有括號相當 -
如何用一行代碼生成
[1,4,9,16,25,36,49,64,81,100]?print([x*x for x in range(1,11)]) -
一行代碼實現刪除列表中重復的值 ?
list(set([1,1,1,2,2,3,1,2,3,3,4,3,4,5,4,6,])) -
如何在函數中設置一個全局變量 ?
用 global關鍵字聲明的 變量 -
logging模塊的作用?以及應用場景?logging 模塊 定義的函數和類為應用程序和庫的開發實現了一個靈活的事件日志系統 并設置了不同的事件等級 -
請用代碼簡答實現
stack。class mystack(object): def __init__(self): self.stack = [] def getval(self): return self.stack.pop(0) def delval(self,value): self.stack.append(value) -
常用字符串格式化哪幾種?
x = 1 xx = 11 print(f"花括號包含變量名{xx}") print("花括號占位映射{0},{1}".format(x,xx)) print("百分號占位,%d"%x) -
簡述 生成器、迭代器、可迭代對象 以及應用場景?
迭代器對象就是實現了iter() 和 next()方法的對象.其中iter()返回迭代器本身,而next()返回容器的下一個元素,在結尾處引發StopInteration異常.生成器和迭代器屬于可迭代對象生成器包含__next__ 方法, 迭代器包含__iter__方法迭代器包含__iter__方法 -
用 Python 實現一個二分查找的函數。
data = [1, 3, 6, 7, 9, 12, 14, 16, 17, 18, 20, 21, 22, 23, 30, 32, 33, 35] # 雙指針法實現二分查找 def binary_search(dataset,find_num): l, r = 0, len(dataset)-1 while l < r-1: mid = (l+r)//2 if dataset[mid]>find_num: r = mid elif dataset[mid]< find_num: l = mid else: print("目標數字下標為%d"% mid) return mid print("找不到目標數值") # binary_search(data, 12) # binary_search(data, 13) # binary_search(data, 23) # binary_search(data, 25) -
談談你對閉包的理解?
在一個外函數中定義了一個內函數,內函數里運用了外函數的臨時變量,并且外函數的返回值是內函數的引用。這樣就構成了一個閉包。一般情況下,在我們認知當中,如果一個函數結束,函數的內部所有東西都會釋放掉,還給內存,局部變量都會消失。但是閉包是一種特殊情況,如果外函數在結束的時候發現有自己的臨時變量將來會在內部函數中用到,就把這個臨時變量綁定給了內部函數,然后自己再結束 -
os和sys模塊的作用?1. os模塊負責程序與操作系統的交互,提供了訪問操作系統底層的接口; 2. sys模塊負責程序與python解釋器的交互,提供了一系列的函數和變量,用于操控python的運行時環境。 -
如何生成一個隨機數?
random.randint(a,b) # 生成a 到 b 范圍內的隨機數 -
如何使用 python 刪除一個文件?
import os os.remove('path/filename') -
談談你對面向對象的理解?
封裝: 將屬性和方法封裝到類的內部,將數據封裝到類的內部,方便調用 繼承: 將類共同的方法提取到基類,提高代碼的復用率 多態: 鴨子模型 新式類(廣度優先) 經典類(深度優先) -
Python 面向對象中的繼承有什么特點?
將類共同的方法提取到基類,提高代碼的復用率 繼承的特點:
1、在繼承中基類的構造(__init__()方法)不會被自動調用,它需要在其派生類的構造中親自專門調用。有別于C#
2、在調用基類的方法時,需要加上基類的類名前綴,且需要帶上self參數變量。區別于在類中調用普通函數時并不需要帶上self參數
3、Python總是首先查找對應類型的方法,如果它不能在派生類中找到對應的方法,它才開始到基類中逐個查找。(先在本類中查找調用的方法,找不到才去基類中找)。
```
-
面向對象深度優先和廣度優先是什么?
經典類遵循深度優先的規則,新式類遵循廣度優先的規則 在 python3 中,都是遵循廣度優先的規則,在 python2.7 以前,應該是遵循深度優先的的規則。兩種規則沒有優劣之分。 深度優先原則: 從左到右 每個都往父類查找,找不到再去查找后面的 廣度優先原則: 先從左到右查詢,查到就不再繼續,當前類沒有繼續查找父類 -
面向對象中 super 的作用?
super() 函數是用于調用父類(超類)的一個方法。 super 是用來解決多重繼承問題的,直接用類名調用父類方法在使用單繼承的時候沒問題,但是如果使用多繼承,會涉及到查找順序(MRO)、重復調用(鉆石繼承)等種種問題。 MRO 就是類的方法解析順序表, 其實也就是繼承父類方法時的順序表。 super() 方法的語法: super(type[, object-or-type]) -
是否使用過 functools 中的函數?其作用是什么?
functools模塊 1. wraps 在裝飾器拷貝被裝飾函數的 __name__ __doc__ 等 2. partial 偏函數, 給函數添加固定參數 3. reduce 在 Python2 中等同于內建函數 reduce 函數的作用是將一個序列歸納為一個輸出 reduce(function, sequence, startValue) 4. lru_cache 允許我們將一個函數的返回值快速地緩存或取消緩存。 -
列舉面向對象中帶雙下劃線的特殊方法,如:
__new__、__init__**str repr getattribute setattribute getitem setitem delitem all mro exit start del module class doc** -
如何判斷是函數還是方法?
from types import MethodType, FunctionType class Bar: def foo(self): pass def foo2(): pass def run(): print("foo 是函數", isinstance(Bar().foo, FunctionType)) print("foo 是方法", isinstance(Bar().foo, MethodType)) print("foo2 是函數", isinstance(foo2, FunctionType)) print("foo2 是方法", isinstance(foo2, MethodType)) if __name__ == '__main__': run() -
靜態方法和類方法區別?
靜態方法 用@staticmethod 裝飾器修飾,可以被類和實例調用 類方法 用@classmethod裝飾器修飾 **必須帶cls 參數,**只能被類調用 -
列舉面向對象中的特殊成員以及應用場景
1. `__doc__`:表示類的描述信息。 2. `__module__`:表示當前操作的對象在那個模塊; 3. `__class__`:表示當前操作的對象的類是什么。 4. `__init__`:構造方法,通過類創建對象時,自動觸發執行。 5. `__call__`:對象后面加括號,觸發執行。 6. `__dict__`:類或對象中的所有成員。 7. `__str__`:如果一個類中定義了__str__方法,那么在打印對象時,默認輸出該方法的返回值。 8. `__getitem__`、`__setitem__`、`__delitem__`:用于索引操作,如字典。以上分別表示獲取、設置、刪除數據。 9. `__iter__`:用于迭代器,之所以列表、字典、元組可以進行for循環,是因為類型內部定義了 `__iter__`。 -
1、2、3、4、5 能組成多少個互不相同且無重復的三位數
import itertools print(len(list(itertools.permutations('12345',3)))) #5x4x3 = 60個 -
什么是反射?以及應用場景?
反射就是通過字符串的形式,導入模塊;通過字符串的形式,去模塊尋找指定函數,并執行。利用字符串的形式去對象(模塊)中操作(查找/獲取/刪除/添加)成員,一種基于字符串的事件驅動!應用場景:當我們動態的輸入一個模塊名的時候就可以使用到反射。通過hasattr,getattr,delattr,setattr等四個函數來操作 -
metaclass 作用?以及應用場景?
元類 實例化結果是類 :orm -
用盡量多的方法實現單例模式。
1. 模塊:Python 的模塊就是天然的單例模式,因為模塊在第一次導入時,會生成 .pyc 文件,當第二次導入時,就會直接加載 .pyc 文件,而不會再次執行模塊代碼。 2. 先執行了類的__new__方法(我們沒寫時,默認調用object.__ new__),實例化對象;然后再執行類的__init__方法,對這個對象進行初始化,所有我們可以基于這個,實現單例模式。 3. 原理:裝飾器用來控制類調用__ call__方法 4. 執行元類的__new__方法和__init__方法用來實例化類對象,__ call__ 方法用來對實例化的對象的實例即類的對象進行控制。__call__方法會調用實例類的 __new__方法,用于創建對象。返回對象給__call__方法,然后調用類對象的 __init__方法,用于對對象初始化 -
裝飾器的寫法以及應用場景。
######################################## # 裝飾器使用 functools.wraps 修飾函數 # 實現執行時間輸出 import time from functools import wraps def timethis(func): ''' 報告執行時間的裝飾器 ''' @wraps(func) def wrapper(*args, **kwargs): start = time.time() result = func(*args, **kwargs) end = time.time() print(func.__name__, end-start) return result return wrapper ########################################### # 添加日志功能 from functools import wraps import logging def logged(level, name=None, massage=None): """ 最外層套一層帶參數的函數,接受參數可作用于內部裝飾器函數上 level 是日志等級 name為日志名,沒傳入默認模塊名 message 為日志內容 ,沒傳入默認函數名 """ def decorate(func): logname = name if name else func.__module__ log = logging.getLogger(logname) logmsg = message if message else func.__name__ @wraps(func) def wrapper(*args, **kwargs): log.log(level,logmsg) return func(*args,**kwargs) return wrapper return decorate -
異常處理寫法以及如何主動跑出異常(應用場景)
try/except 關鍵字 捕獲并處理異常 raise 關鍵字主動拋出異常 -
什么是面向對象的 mro
Python是支持面向對象編程的,同時也是支持多重繼承的。 而支持多重繼承,正是Python的方法解析順序(Method Resoluthion Order, 或MRO)問題出現的原因所在。 -
isinstance 作用以及應用場景?
isinstance作用:來判斷一個對象是否是一個已知的類型; isinstance(obj,type) 對象類型相同返回Ture -
寫代碼并實現:
Given an array of integers, return indices of the two numbers such that they add up to a specific target.You may assume that each input would have exactly one solution, and you may not use the same element twice. Example: Given nums = [2, 7, 11, 15], target = 9,Because nums[0] + nums[1] = 2 + 7 = 9, return [0, 1]class Solution: def twoSum(self, nums: List[int], target: int) -> List[int]: dic = dict() for i,n in enumerate(nums): if target-n in dic: return [dic.get(target-n),i] dic[n] = i -
json 序列化時,可以處理的數據類型有哪些?如何定制支持 datetime 類型?
可處理 列表和字典類型, 或字典和列表的嵌套# 自定義時間序列化轉換器 import json from json import JSONEncoder from datetime import datetime class ComplexEncoder(JSONEncoder): def default(self, obj): if isinstance(obj, datetime): return obj.strftime('%Y-%m-%d %H:%M:%S') else: return super(ComplexEncoder,self).default(obj) d = { 'name':'alex','data':datetime.now()} print(json.dumps(d,cls=ComplexEncoder)) # {"name": "alex", "data": "2018-05-18 19:52:05"} -
json 序列化時,默認遇到中文會轉換成 unicode,如果想要保留中文怎么辦?
## dumps函數添加參數ensure_ascii 設置為False import json a=json.dumps({"ddf":"你好"},ensure_ascii=False) print(a) #{"ddf": "你好"} -
什么是斷言?應用場景?
assert 斷言, 判斷一個條件,為真 不做任何事情,為假會拋出AssertError并且包含錯誤信息 運用: - 防御性編程: - 運行時檢查程序邏輯: - 檢查約定:“如果你傳給我一個非空字符串,我保證傳會字符串的第一個 字母并將其大寫。” - 程序常量: - 檢查文檔: 在測試代碼的時候使用斷言也是可接受的,是一種很方便的單元測試方法 -
有用過 with statement 嗎?它的好處是什么?
- 上下文管理協議(Context Management Protocol):包含方法__enter__()和__exit__(),支持該協議的對象要實現這兩個方法。 - 上下文管理器(Context Manager):支持上下文管理協議的對象,這種對象實現了__enter__()和__exit__()方法。上下文管理器定義執行with語句時要建立的運行時上下文,負責執行with語句塊上下文中的進入與退出操作。通常使用with語句調用上下文管理器,也可以通過直接調用其方法來使用。 1. 執行 statement中的表達式; 2. 不管是否執行過程中是否發生了異常,執行上下文管理器的__exit__()方法,__**exit__**()方法負責執行 “清理” 工作,如釋放資源等。如果執行過程中沒有出現異常,或者語句體中執行了語句break/continue/return,則以None作為參數調用__exit__(None, None, None);如果執行過程中出現異常,則使用sys.exc_info得到的異常信息為參數調用__exit__(exc_type, exc_value, exc_traceback); 3. 出現異常時,如果__exit__(type, value, traceback)返回 False,則會重新拋出異常,讓with之外的語句邏輯來處理異常,這也是通用做法;如果返回 True,則忽略異常,不再對異常進行處理 -
使用代碼實現查看列舉目錄下的所有文件。
import os def list_all_files(cur_dir): _files = [] # 列出當前目錄下所有文件和目錄 list_files = os.listdir(cur_dir) for i in range(len(list_files)): path = os.path.join(cur_dir,list_files[i]) if os.path.isfile(path): _files.append(path) if os.path.isdir(path): _files.extend(list_all_files(path) return _files -
簡述 yield 和 yield from 關鍵字。
yield 函數中以yield 關鍵字來返回值,這該函數為一個生成器 ps: 生成器,延時加載,節省空間 yield from + 可迭代對象(list、tuple、range函數)返回另一個生成器

浙公網安備 33010602011771號