- 爲什麼學習Python
愛好
- 通過什麼途徑學習Python
首先看視頻自學,然後看書自學,最後報班學。
- 談談Python和其他語言的區別
Python屬於解釋型語言,當程序運行時,是一行一行的解釋並運行,調試程序簡單,開發效率高。
特點:
語法簡潔優美,功能強大,標準庫與第三方庫都非常強大。具有很強大的可移植性、可擴展性、可嵌入性。
缺點:運行速度慢
- 簡述解釋型和編譯型編程語言
解釋型:就是邊解釋邊執行
編譯型:編譯後再執行
- Python的解釋器種類以及相關特點
CPython
當我們從Python官方網站下載並安裝好Python 3.6後,我們就直接獲得了一個官方版本的解釋器:CPython。這個解釋器是用C語言開發的,所以叫CPython。在命令行下運行python就是啓動CPython解釋器。
CPython是使用最廣的Python解釋器。教程的所有代碼也都在CPython下執行。
IPython
IPython是基於CPython之上的一個交互式解釋器,也就是說,IPython只是在交互方式上有所增強,但是執行Python代碼的功能和CPython是完全一樣的。好比很多國產瀏覽器雖然外觀不同,但內核其實都是調用了IE。
CPython用>>>作爲提示符,而IPython用In [序號]:作爲提示符。
PyPy
PyPy是另一個Python解釋器,它的目標是執行速度。PyPy採用JIT技術,對Python代碼進行動態編譯(注意不是解釋),所以可以顯著提高Python代碼的執行速度。
絕大部分Python代碼都可以在PyPy下運行,但是PyPy和CPython有一些是不同的,這就導致相同的Python代碼在兩種解釋器下執行可能會有不同的結果。如果你的代碼要放到PyPy下執行,就需要了解PyPy和CPython的不同點。
Jython
Jython是運行在Java平臺上的Python解釋器,可以直接把Python代碼編譯成Java字節碼執行。
IronPython
IronPython和Jython類似,只不過IronPython是運行在微軟.Net平臺上的Python解釋器,可以直接把Python代碼編譯成.Net的字節碼。
- 位和字節的關係
1字節 = 8位
- b、B、KB、MB、GB的關係
1B = 8 b
1KB = 1024 B
1MB = 1024 KB
1 GB = 1024 MB
- PE8規範
1、使用4個空格而不是tab鍵進行縮進。
2、每行長度不能超過79
3、使用空行來間隔函數和類,以及函數內部的大塊代碼
4、必要時候,在每一行下寫註釋
5、使用文檔註釋,寫出函數註釋
6、在操作符和逗號之後使用空格,但是不要在括號內部使用
7、命名類和函數的時候使用一致的方式,比如使用CamelCase來命名類,使用lower_case_with_underscores來命名函數和方法
8、在類中總是使用self來作爲默認
9、儘量不要使用魔法方法
10、默認使用UTF-8,甚至ASCII作爲編碼方式
11、換行可以使用反斜槓,最好使用圓括號。
- 通過代碼實現如下轉換
# 二進制轉換成十進制
v = "0b1111011"
b = int(v,2)
print(b) # 123
# 十進制轉換成二進制
v2 = 18
print(bin(int(v2)))
# 0b10010
# 八進制轉換成十進制
v3 = "011"
print(int(v3))
# 11
# 十進制轉換成八進制
v4 = 30
print(oct(int(v4)))
# 0o36
# 十六進制轉換成十進制
v5 = "0x12"
print(int(v5,16))
# 18
# 十進制轉換成十六進制
v6 = 87
print(hex(int(v6)))
# 0x57
- 請編寫一個函數實現將IP地址轉換成一個整數
def bin_to_dec(obj):
return int(''.join([bin(int(x))[2:].rjust(8, '0') for x in obj.split('.')]), 2)
print(bin_to_dec('127.0.0.1'))
# 2130706433
- Python遞歸的最大層數
998
- 求結果(and or or)
print(1 or 3) # 1
print(1 and 3) # 3
print(0 and 2 and 1) # 0
print(0 and 2 or 1) # 1
print(0 and 2 or 1 or 4) # 1
print(0 or False and 1) # False
總結:
優先級:not > and > or
- ascii、unicode、utf-8、gbk區別
ascii 最多隻能用8位來表示(一個字節),即:2**8 = 256,所以,ASCII碼最多隻能表示 256 個符號。
unicode 萬國碼,任何一個字符用兩個字節表示
utf-8 萬國碼的升級版 一箇中文字符用三個字節 英文用一個字節 歐洲用2個字節
gbk 國內版本 一箇中文字符用2個字節 英文用一個字節
- 字節碼和機器碼的區別
機器碼,學名機器語言指令,有時也被稱爲原生碼,是電腦的CPU可直接解讀的數據。
字節碼是一種中間狀態(中間碼)的二進制代碼(文件)。需要直譯器轉譯後才能成爲機器碼。
- 三元運算寫法和應用場景
# 語法
# 結果1 if 條件 else 結果2
# 若條件成立返回結果1,不成立返回結果2
print(1 if 2 > 1 else 2)
# 1
- Python3和Python2區別
1:打印時,py2需要可以不需要加括號,py3 需要
python 2 :print (‘lili’) , print ‘lili’
python 3 : print (‘lili’)
python3 必須加括號
exec語句被python3廢棄,統一使用exec函數
2:內涵
Python2:1,臃腫,源碼的重複量很多。
2,語法不清晰,摻雜着C,php,Java,的一些陋習。
Python3:幾乎是重構後的源碼,規範,清晰,優美。
3、輸出中文的區別
python2:要輸出中文 需加 # -- encoding:utf-8 --
Python3 : 直接搞
4:input不同
python2 :raw_input
python3 :input 統一使用input函數
5:指定字節
python2在編譯安裝時,可以通過參數-----enable-unicode=ucs2 或-----enable-unicode=ucs4分別用於指定使用2個字節、4個字節表示一個unicode;
python3無法進行選擇,默認使用 ucs4
查看當前python中表示unicode字符串時佔用的空間:
impor sys
print(sys.maxunicode)
#如果值是65535,則表示使用usc2標準,即:2個字節表示
#如果值是1114111,則表示使用usc4標準,即:4個字節表示
6:py2:xrange
range
py3:range 統一使用range,Python3中range的機制也進行修改並提高了大數據集生成效率
7:在包的知識點裏
包:一羣模塊文件的集合 + __init__
區別:py2 : 必須有__init__
py3:不是必須的了
8:不相等操作符"<>“被Python3廢棄,統一使用”!="
9:long整數類型被Python3廢棄,統一使用int
10:迭代器iterator的next()函數被Python3廢棄,統一使用next(iterator)
11:異常StandardError 被Python3廢棄,統一使用Exception
12:字典變量的has_key函數被Python廢棄,統一使用in關鍵詞
13:file函數被Python3廢棄,統一使用open來處理文件,可以通過io.IOBase檢查文件類型
- 一行代碼實現數值交換
a,b = b,a
- Python3和Python2中int和long區別
在python3裏,只有一種整數類型int,大多數情況下,和python2中的長整型類似。
- xrange和range的區別
都在循環時使用,xrange內存性能更好,xrange用法與range完全相同,range一個生成list對象,xrange是生成器
要生成很大的數字序列的時候,用xrange會比range性能優很多,因爲不需要一上來就開闢一塊很大的內存空間。
在Python3中range實現和xrange一致,xrange被捨棄
- 文件操作時,xreadlines和readlines的區別
readlines返回列表
xreadlines返回生成器
- 列舉布爾值爲False的常見值
0,“”,{},[],(),set()
- lambda表達式格式以及應用場景
# 語法
# 函數名 = lambda 參數:返回值
print(list(map(lambda x:x*x, [1, 2, 3, 4])))
# [1, 4, 9, 16]
- pass的作用
pass是空語句,是爲了保持程序結構的完整性。pass 不做任何事情,一般用做佔位語句。
- *arg和**kwarg作用
*args代表位置參數,它會接收任意多個參數並把這些參數作爲元祖傳遞給函數。
**kwargs代表的關鍵字參數,返回的是字典,位置參數一定要放在關鍵字前面
- is和==的區別
is用於判斷內存地址是否一致
==判斷值是否一致
- 談談Python的深淺拷貝以及實現方法和應用場景
淺拷貝只是增加了一個指針指向一個存在的地址,
而深拷貝是增加一個指針並且開闢了新的內存,這個增加的指針指向這個新的內存,採用淺拷貝的情況,釋放內存,會釋放同一內存,深拷貝就不會出現釋放同一內存的錯誤
# 淺拷貝 指向共有的地址
li1 = [1, 2, 3, [4, 5], 6]
li2 = li1.copy()
li1[3].append(7)
print(li1, li2) # [1, 2, 3, [4, 5, 7], 6] [1, 2, 3, [4, 5, 7], 6]
# 深拷貝 重指向
li1 = [1, 2, 3, [4, 5], 6]
li2 = copy.deepcopy(li1)
li1[3].append(7)
print(li1, li2) # [1, 2, 3, [4, 5, 7], 6] [1, 2, 3, [4, 5], 6]
- Python垃圾回收機制
引用計數、標記清除、分代回收
- Python的可變數據類型和不可變數據類型
可變數據類型:列表、字典、可變集合
不可變數據類型:數字、字符串、元組、不可變集合
- 求結果
def multipliers():
return [lambda x:i*x for i in range(4)]
print([m(2) for m in multipliers()])
# [6,6,6,6]
- 求結果
v = dict.fromkeys(['k1', 'k2'], [])
v['k1'].append(666)
print(v) # {'k1': [666], 'k2': [666]}
v['k1'] = 777
print(v) # {'k1': 777, 'k2': [666]}
# 分析:創建字典時k1和k2指向同一個空列表,往k1指向的空列表添加值,k2對應的值也改變
- 列舉常見的內置函數
abs() # 求絕對值
map() # 映射
filter() # 過濾
isinstance # 判斷一個對象是否是一個已知的類型,考慮繼承
type() # 判斷一個對象是否是一個已知的類型,不考慮繼承
zip() # 拉鍊函數(壓縮)
- filter、map、reduce的作用
# filter 過濾
print(list(filter(lambda x: x > 2, [1, 2, 3, 4]))) # [3, 4]
# map 映射
print(list(map(abs, [-1, -2, -3, 4]))) # [1, 2, 3, 4]
# reduce 累計操作
from functools import reduce
print(reduce(lambda x, y: x + y, [1, 2, 3, 4])) # 10
- 一行代碼實現99乘法表
print('\n'.join([' '.join([str(x)+'*'+str(y)+'='+str(x*y) for y in range(1,x+1)])for x in range(1,10)]))
- 如何安裝第三方模塊
pip install
- 常用的模塊都有哪些
re模塊,os模塊,json模塊,time模塊,functools模塊
- re的match和search區別
match從字符串起始位置開始匹配
search掃描整個字符串返回第一個成功的匹配
- 什麼是正則的貪婪匹配
匹配一個字符串沒有節制,能匹配多少就匹配多少
- 求結果
print([ i % 2 for i in range(10) ]) # [0, 1, 0, 1, 0, 1, 0, 1, 0, 1]
print([ i for i in range(10) ]) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(( i % 2 for i in range(10) )) # <generator object <genexpr> at 0x000001CFF36516D0> 返回一個生成器
- 求結果
1 or 2 # 1
1 and 2 # 2
1 < (2 == 2) # False
1 < 2 == 2 # True
- def func(a,b=[])這種寫法有什麼坑
def func(a,b = []):
b.append(a)
return b
print(func(1)) # [1]
print(func(2)) # [1, 2]
每次調用func如果不傳入b,則b都指向同一個列表
- 如何實現"1,2,3"變成[‘1’,‘2’,‘3’]
print("1,2,3".split(',')) # ['1', '2', '3']
- 如何實現[‘1’,’2’,’3’]變成[1,2,3]
print([int(x) for x in ['1', '2', '3']])
- a = [1,2,3] 和 b = [(1),(2),(3) ] 以及 b = [(1,),(2,),(3,) ] 的區別?
a表示含有3個數字的列表
b表示含有3個數字的列表,但每個數字經過()運算,故a is not b
c表示含有3個元組的列表,每個元組含有一個數字
- 如何用一行代碼生成[1,4,9,16,25,36,49,64,81,100]
print([i*i for i in range(1,11)]) # [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
- 一行代碼實現刪除列表中重複的值
print(list(set([1, 2, 3, 4, 45, 1, 2, 343, 2, 2]))) # [1, 2, 3, 4, 45, 343]
- 如何在函數中設置一個全局變量
a = 1
def func(oj):
global a
a = oj
return a
print(a) # 1
print(func(3)) # 3
print(a) # 3
- 常用字符串格式化哪幾種?
佔位符%
format
- 簡述 生成器、迭代器、可迭代對象?
迭代器
含有__iter__
和__next__
方法 (包含__next__
方法的可迭代對象就是迭代器)
生成器
包括含有yield這個關鍵字,生成器也是迭代器,調動next把函數變成迭代器。
可迭代對象
一個類內部實現__iter__
方法且返回一個迭代器。
- 談談你對閉包的理解
def foo():
m=3
n=5
def bar():
a=4
return m+n+a
return bar
print(foo()()) # 12
bar在foo函數的代碼塊中定義。我們稱bar是foo的內部函數。
在bar的局部作用域中可以直接訪問foo局部作用域中定義的m、n變量。
簡單的說,這種內部函數可以使用外部函數變量的行爲,就叫閉包。
- os和sys模塊的作用
os模塊負責程序與操作系統的交互,提供了訪問操作系統底層的接口;
sys模塊負責程序與python解釋器的交互,提供了一系列的函數和變量,用於操控python的運行時環境。
- 如何生成一個隨機數
random模塊
- 如何使用python刪除一個文件
os.remove()
- 談談你對面向對象的理解
面對對象是一種編程思想,以類的眼光來來看待事物的一種方式。將有共同的屬性和方法的事物封裝到同一個類下面。
繼承:將多個類的共同屬性和方法封裝到一個父類下面,然後在用這些類來繼承這個類的屬性和方法
封裝:將有共同的屬性和方法封裝到同一個類下面
- 第一層面:創建類和對象會分別創建二者的名稱空間,我們只能用類名.或者obj.的方式去訪問裏面的名字,這本身就是一種封裝
- 第二層面:類中把某些屬性和方法隱藏起來(或者說定義成私有的),只在類的內部使用、外部無法訪問,或者留下少量接口(函數)供外部訪問。
多態:Python天生是支持多態的。指的是基類的同一個方法在不同的派生類中有着不同的功能
- Python面向對象中的繼承有什麼特點
繼承概念的實現方式主要有2類:實現繼承、接口繼承。
實現繼承是指使用基類的屬性和方法而無需額外編碼的能力;
接口繼承是指僅使用屬性和方法的名稱、但是子類必須提供實現的能力(子類重構爹類方法);
python 兩種類:經典類 新式類
python3 新式類 —— 都默認繼承object class Animal(object): == class Animal:
python2 經典類和新式類 並存
class Animal: 經典類 —— 繼承順序 個別使用方法
class Animal(object): 新式類
繼承分爲單繼承和多繼承
Python是支持多繼承的
如果沒有指定基類,python的類會默認繼承object類,object是所有python類的基類,它提供了一些常見方法(如__str__)的實現。
- 面向對象深度優先和廣度優先是什麼
Python的類可以繼承多個類,Python的類如果繼承了多個類,那麼其尋找方法的方式有兩種
當類是經典類時,多繼承情況下,會按照深度優先方式查找 py3
當類是新式類時,多繼承情況下,會按照廣度優先方式查找 py2
簡單點說就是:經典類是縱向查找,新式類是橫向查找
經典類和新式類的區別就是,在聲明類的時候,新式類需要加上object關鍵字。在python3中默認全是新式類
- 面向對象中super的作用
用於子類繼承基類的方法
- 是否使用過functools中的函數?其作用是什麼?
wraps()用於裝飾裝飾器內部函數,使函數說明等依舊返回原函數
reduce()累計計算
- 列舉面向對象中帶雙下劃線的特殊方法
__new__
:生成實例__init__
:生成實例的屬性__call__
:實例對象加( )會執行def__call__
:… 方法裏邊的內容。__del__
:析構方法,當對象在內存中被釋放時,自動觸發執行。如當 del obj 或者應用程序運行完畢時,執行該方法裏邊的內容。__enter__
和__exit__
:出現with語句,對象的__enter__
被觸發,有返回值則賦值給as聲明的變量;with中代碼塊執行完畢時執行__exit__
裏邊的內容。__module__
:表示當前操作的對象在那個模塊 obj.__module__
__class__
:表示當前操作的對象的類是什麼 obj.__class__
__doc__
:類的描述信息,該描述信息無法被繼承__str__
:改變對象的字符串顯示 print函數 —>obj.__str__()
__repr__
:改變對象的字符串顯示 交互式解釋器 —>obj.__repr__()
-
`__format__`:自定製格式化字符串
__slots__
:一個類變量 用來限制實例可以添加的屬性的數量和類型
- 如何判斷是函數還是方法
看他的調用者是誰,如果是類,就需要傳入一個參數self的值,這時他就是一個函數,
如果調用者是對象,就不需要給self傳入參數值,這時他就是一個方法
- 靜態方法和類方法區別
儘管 classmethod 和 staticmethod 非常相似,但在用法上依然有一些明顯的區別。classmethod 必須有一個指向類對象的引用作爲第一個參數,而 staticmethod 可以沒有任何參數。
- 什麼是反射
# 反射的核心本質就是以字符串的形式去導入個模塊,利用字符串的形式去執行函數。
hasattr()
getattr()
setattr()
delattr()
- 裝飾器器的寫法以及應用場景
含義:裝飾器本質就是函數,爲其他函數添加附加功能
原則:
不修改被修飾函數的代碼
不修改被修飾函數的調用方式
應用場景:
無參裝飾器在用戶登錄 認證中常見
有參裝飾器在flask的路由系統中見到過
from functools import wraps
def func(fun):
@wraps(fun)
def wrapper(*args, **kwargs):
print("Hello")
return fun(*args, **kwargs)
return wrapper
@func
def show():
print("show")
show()
# Hello
# show
- 異常處理寫法以及如何主動拋出異常
try:
pass
except ValueError:
pass
# raise語法
# raise [Exception [, args [, traceback]]]
# 語句中 Exception 是異常的類型,args 是自已提供的異常參數。
- 什麼是面向對象的mro
方法解析順序
- 經典類(calssic class),深度優先遍歷
- 在python2.2中提出了type和class的統一,出現了一個內建類型以及自定義類的公共祖先object,即新式類(new-style class)預計算
- python2.3之後新式類的C3算法,這是python3唯一支持的方式
- isinstance作用以及應用場景
isinstance(對象,類) 判斷這個對象是不是這個類或者這個類的子類的實例化
class Foo:
pass
class Bar(Foo):
pass
f = Foo()
b = Bar()
print(isinstance(b, Bar)) # True
print(isinstance(f, Foo)) # True
print(isinstance(b, Foo)) # True
- json序列化時,可以處理的數據類型有哪些
- 字典中的key必須是字符串
- json 只支持列表,字典,數值,字符串以及布爾值
- json序列化時,默認遇到中文會轉換成unicode,如果想要保留中文怎麼辦
在序列化時,中文漢字總是被轉換爲unicode碼,在dumps函數中添加參數ensure_ascii=False即可解決。
- 什麼是斷言
條件成立(布爾值爲True)則繼續往下,否則拋出異常,一般用於:滿足某個條件之後,才能執行,否則應該拋出異常。
assert condition
li = [1, 2]
assert len(li) >= 5, "列表元素小於5"
Traceback (most recent call last):
File "D:/python/test1/day06.py", line 41, in <module>
assert len(li) >= 5, "列表元素小於5"
AssertionError: 列表元素小於5