Python 經典面試題彙總之基礎篇

基礎篇

1:爲何學習Python

公司建議使用Python,而後本身經過百度和向有學過Python的同窗瞭解了Python。Python這門語言,入門比較簡單,它簡單易學,生態圈比較強大,涉及的地方比較多,特別是在人工智能,和數據分析這方面。在將來我以爲是往自動化,人工智能這方面發展的,因此學習了Python。

2:經過什麼途徑學習Python

自學,練項目,到GitHub上面找一些小項目學習。

3:談談對Python和其餘語言的區別

Python屬於解釋型語言,當程序運行時,是一行一行的解釋,並運行,因此調式代碼很方便,開發效率高,還有龜叔給Python定位是任其自由發展、優雅、明確、簡單,因此在每一個領域都有建樹,全部它有着很是強大的第三方庫,
特色:
語法簡潔優美,功能強大,標準庫與第三方庫都很是強大,並且應用領域也很是廣;
可移植性,可擴展性,可嵌入性。
缺點:
  運行速度慢。
- 解釋型 - Python/php  (java、C 編譯型) - 弱類型
  - Python     (java、C 強類型)
- 動態語言
  - Python     (java、C 靜態型)

(1)與Java相比:在不少方面,Python比java要簡單,好比java中全部變量必須聲明才能使用,而Python不須要聲明,用少許的代碼構建出不少功能;(高效的高級數據結構)php

(2)與PHP相比:python標準包直接提供了工具,而且相對於PHP代碼更易於維護;java

(3)Python與C相比:python

Python 和 C Python這門語言是由C開發而來mysql

  對於使用:Python的類庫齊全而且使用簡潔,若是要實現一樣的功能,Python 10行代碼能夠解決,C可能就須要100行甚至更多.
  對於速度:Python的運行速度相較與C,絕逼是慢了git

Python的優點:

一、Python 易於學習;redis

二、用少許的代碼構建出不少功能;(高效的高級數據結構)算法

三、Python 擁有最成熟的程序包資源庫之一;sql

四、Python徹底支持面向對象;shell

五、Python 是跨平臺且開源的;數據庫

六、動態類型.

4:簡述解釋型和編譯型編程語言

解釋型:就是邊解釋邊執行(Python,php)
編譯型:編譯後再執行(c、java、c#)

5:Python的解釋器種類以及相關特色?

CPython
是官方版本的解釋器:CPython。是使用C語言開發的,因此叫CPython。在命令行下運行python就是啓動CPython解釋器。
CPython是使用最廣的Python解釋器。教程的全部代碼也都在CPython下執行。

IPython
IPython是基於CPython之上的一個交互式解釋器,也就是說,IPython只是在交互方式上有所加強,可是執行Python代碼的功能和CPython是徹底同樣的。CPython用>>>做爲提示符,而IPython用In [序號]:做爲提示符。
PyPy
由Python寫的解釋器,它的執行速度是最快。PyPy採用JIT技術,對Python代碼進行動態編譯(注意不是解釋),
絕大部分Python代碼均可以在PyPy下運行,可是PyPy和CPython有一些是不一樣的,這就致使相同的Python代碼在兩種解釋器下執行可能會有不一樣的結果。

Jython
Jython是運行在Java平臺上的Python解釋器,能夠直接把Python代碼編譯成Java字節碼執行。

IronPython
IronPython和Jython相似,只不過IronPython是運行在.Net平臺上的Python解釋器,能夠直接把Python代碼編譯成.Net的字節碼。

小結:
  Python的解釋器不少,但使用最普遍的仍是CPython。若是要和Java或.Net平臺交互,最好的辦法不是用Jython或IronPython,而是經過網絡調用來交互,確保各程序之間的獨立性。

6:位和字節的關係

1字節 = 8 位
位(bit),數據存儲是以「字節」(Byte)爲單位,數據傳輸是以大可能是以「位」(bit,又名「比特」)爲單位,
一個位就表明一個0或1(即一個二進制),二進制是構成存儲器的最小單位,每8個位(bit,簡寫爲b)組成一個字節(Byte,簡寫爲B),
字節是最小一級的信息單位。

7:b、B、KB、MB、GB的關係

b --->位(bit)    

B --->字節      一個字節等於8位

1B = 8 bit

1kb = 1024 B

1 MB = 1024 KB

1 GB = 1024 MB

8:PEP8規範

一、使用4個空格而不是tab鍵進行縮進。
二、每行長度不能超過80
三、使用空行來間隔函數和類,以及函數內部的大塊代碼
四、必要時候,在每一行下寫註釋
五、使用文檔註釋,寫出函數註釋
六、在操做符和逗號以後使用空格,可是不要在括號內部使用
七、命名類和函數的時候使用一致的方式,好比使用CamelCase來命名類,使用lower_case_with_underscores來命名函數和方法
八、在類中老是使用self來做爲默認
九、儘可能不要使用魔法方法
十、默認使用UTF-8,甚至ASCII做爲編碼方式
十一、換行可使用反斜槓,最好使用圓括號
十二、不要在一句import中多個庫

空格的使用:
  1. 各類右括號前不要加空格
  2. 逗號、冒號前不要加空格
  3. 函數的左括號前不要加空格。如Func(1)
  4. 序列的左括號前不要加空格。如list[2]
  5. 操做符左右各加一個空格,不要爲了對齊增長空格
  6. 函數默認參數使用的賦值符左右省略空格
  7. 不要將多句語句寫在同一行
  8. if/for/while語句中,即便執行語句只有一句,也必須另起一行
 包名小寫(不含下劃線),函數名小寫(可含下劃線),常量名大寫(可含下劃線),類名駝峯寫法,類屬性小寫(可含下劃線)。

9:經過代碼實現以下轉換(進制之間轉換)

# 二進制轉換成十進制-->int
v = "0b1111011"
b = int(v,2)
print(b)  # 123


# 十進制轉換成二進制--->bin
v2 = 18
print(bin(int(v2)))
# 0b10010

# 八進制轉換成十進制
v3 = "011"
print(int(v3,8))
# 11

# 十進制轉換成八進制:---> oct
v4 = 30
print(oct(int(v4)))
# 0o36

# 十六進制轉換成十進制:
v5 = "0x12"
print(int(v5,16))
# 18

# 十進制轉換成十六進制:---> hex
v6 = 87
print(hex(int(v6)))
# 0x57

10:請編寫一個函數實現將IP地址轉換成一個整數

請編寫一個函數實現將IP地址轉換成一個整數。
如 10.3.9.12 轉換規則爲:
        10            00001010

         3            00000011

         9            00001001

        12            00001100

再將以上二進制拼接起來計算十進制結果:00001010 00000011 00001001 00001100 = ?


def v1(addr):
    # 取每一個數
    id = [int(x) for x in addr.split(".")]
    print(id)
    return sum(id[i] << [24, 16, 8, 0][i] for i in range(4))

print(v1("127.0.0.1"))

# [127, 0, 0, 1]
# 2130706433

11:python遞歸的最大層數?998

12:求結果(and or or)

1. 求結果:1 or 3
print(1 or 3)  # 1

2. 求結果:1 and 3
print(1 and 3)  # 3

3. 求結果:0 and 2 and 1
print(0 and 2 and 1)  # 0

4. 求結果:0 and 2 or 1
print(0 and 2 or 1)  # 1

5. 求結果:0 and 2 or 1 or 4
print(0 and 2 or 1 or 4)  # 1

6. 求結果:0 or Flase and 1
print(0 or False and 1)  # Flase

總結:
  # x or y 若是 x爲真,則值爲x,   不然爲y
  # x and y 若是 x 爲真,則值爲 y,不然爲 x

運算符

1. 求結果:2 & 5(與)

print(2 & 5)  # 10 & 101 => 000 => 0

2. 求結果:2 ^ 5即2 | 5(或)

print(2 ^ 5)  # 10 ^ 101 => 111 => 1*2**0+1*2**1+1*2**2=1+2+4=7

13:ascii、unicode、utf-八、gbk 區別

Python2內容進行編碼(默認ascii),而Python3對內容進行編碼的默認爲unicode。
ascii    最多隻能用8位來表示(1個字節),即:2**8 = 256,因此,ASCII碼最多隻能表示 256 個符號。
unicode  萬國碼,任何一個字符佔2個字節
utf-8    萬國碼的升級版  一箇中文字符佔3個字節   英文是1個字節  歐洲的是2個字節
gbk      國內版本  一箇中文字符佔2個字節   英文是1個字節
gbk 轉 utf-8  需經過媒介 unicode

14:字節碼和機器碼的區別

機器碼,學名機器語言指令,有時也被稱爲原生碼,是電腦的CPU可直接解讀的數據。

字節碼是一種中間狀態(中間碼)的二進制代碼(文件)。須要直譯器轉譯後才能成爲機器碼。

什麼是機器碼
機器碼(machine code),學名機器語言指令,有時也被稱爲原生碼(Native Code),是電腦的CPU可直接解讀的數據。
一般意義上來理解的話,機器碼就是計算機能夠直接執行,而且執行速度最快的代碼。

總結:機器碼是電腦CPU直接讀取運行的機器指令,運行速度最快,可是很是晦澀難懂,也比較難編寫 什麼是字節碼 字節碼(Bytecode)是一種包含執行程序、由一序列 op 代碼/數據對 組成的二進制文件。
字節碼是一種中間碼,它比機器碼更抽象,須要直譯器轉譯後才能成爲機器碼的中間代碼。 總結:字節碼是一種中間狀態(中間碼)的二進制代碼(文件)。須要直譯器轉譯後才能成爲機器碼。
#is  比較的是內存地址
#==  比較的是值
#int     具備範圍:-5---256
#對於int小數據池
範圍:-5----256 建立的相間的數字,都指向同一個內存地址

#對於字符串
一、小數據池 若是有空格,那指向兩個內存地址,
二、長度不能超過 20
三、不能用特殊字符

i = 'a'*20
j = 'a'*20
print(i is j)   # True

i = "a"*21
j = "a"*21
print(i is j)   # False

15:三元運算寫法和應用場景?

應用場景:簡化if語句
# 關於三元運算 # 結果+ if + 條件 + else + 結果 result='gt' if 1>3 else 'lt' print(result) # lt # 理解:若是條件爲真,把if前面的值賦值給變量,不然把else後面的值賦值給變量。 lambda 表達式 temp = lambda x,y:x+y print(temp(4,10)) # 14 可替代: def foo(x,y): return x+y print(foo(4,10)) # 14

16:Python3和Python2的區別?

1:打印時,py2須要能夠不須要加括號,py3 須要
python2 :print ('lili') , print 'lili'
python3 : print ('lili')   
python3 必須加括號

exec語句被python3廢棄,統一使用exec函數。

2:內涵
Python2:1,臃腫,源碼的重複量不少。
         2,語法不清晰,摻雜着C,php,Java,的一些陋習。
Python3:幾乎是重構後的源碼,規範,清晰,優雅。

三、輸出中文的區別
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檢查文件類型

17:用一行代碼實現數值交換

a = 1 
b = 2

a, b = b, a

18:Python3和Python2中int和long區別

在python3裏,只有一種整數類型int。大多數狀況下,和python2中的長整型相似。

19:xrange和range的區別

都在循環時使用,xrange內存性能更好,xrange用法與range徹底相同,range一個生成list對象,xrange是生成器。

要生成很大的數字序列的時候,用xrange會比range性能優不少,由於不須要一上來就開闢一塊很大的內存空間。

在Python2中:

range([start,] stop[, step]),根據start與stop指定的範圍以及step設定的步長,生成一個序列

xrange用法與range徹底相同,所不一樣的是生成的不是一個數組,而是一個生成器。

由上面的示例能夠知道:要生成很大的數字序列的時候,用xrange會比range性能優不少,由於不須要一上來就開闢一塊很大的內存空間,這兩個基本上都是在循環的時候用。

在 Python3 中,range() 是像 xrange() 那樣實現,xrange()被拋棄。

20:文件操做時:xreadlines和readlines的區別?

readlines     返回一個列表

xreadlines   返回一個生成器

21:列列舉布爾值爲False的常見值?

0,"",{},[],(),set(),False,負數,不成立的表達式,None,等。

22:字符串、列表、元組、字典每一個經常使用的5個方法?

字符串:
字符串用單引號(')或雙引號(")括起來,不可變。

s.strip(c):去除空格或指定的字符c;lstrip/rstrip;
s.zfill(w):右對齊,寬度小於w用0前補;
s.ljust(w,c):左對齊,寬度w,填充符c;rjust()右對齊。
s.join(q):用"s"將序列"q"中的元素串起來;
s.partition(sep):以sep爲分隔符,把字符串分割,返回一個元組(包含分割符);
s.split(sep=None, maxsplit=-1):把字符串以sep爲分隔符分割,maxsplit爲分割次數,返回一個列表(不包含分割符);
s.find(t):返回t的最左位置,未找到,返回-1;
s.index(t):返回t的最左位置,未找到,返回ValueError異常;
s.capitalize():第一個字母變大寫;
s.title():每一個單詞首字母大寫;
s.center(width, fillchar=None):字符串內容居中,在給定的字符串長度width中內容居中,兩邊用提供的字符fillchar填充,fillchar默認爲空;
s.count(sub, start=None, end=None):在指定位置start與end之間,計算sub字符的數量;
s.endswith(suffix, start=None, end=None):判斷字符串在start與end位置之間是否是以某個子序列suffix結尾,相似方法還可有startwith();
s.replace(old, new, count=None):把字符串中某個子序列old替換成一個新序列new,count是替換數,返回一個新字符串;
s.isdigit():判斷是否全是數字;
s.isalpha():判斷是否全是字母;
s.isalnum():判斷是否包含字母或數字;
s.isspace():判斷是不是空字符串;
s[start:stop:step]:切片,截取子字符串。

 

字典:
1:無序(不能索引) 2:數據關聯性強 3:鍵值對,鍵值對。惟一一個映射數據類型。 字典的鍵必須是可哈希的,不可變類型。 在同一個字典中,鍵(key)必須是惟一的。
列表是有序的對象集合,字典是無序的對象集合。二者之間的區別在於:字典當中的元素是經過鍵來存取的,而不是經過偏移存取

1)clear(self):清除字典中的全部元素。
2)copy(self):複製一份元組,至關於一次淺拷貝。
3)fromkeys(self, iter, value=None):分別以iter中的元素爲鍵,以value爲值,建立一個字典。
4)get(self, k, d=None):獲取字典中鍵爲k的值,若是字典中不包含k,則給出d值,d默認爲None。
5)items(self):遍歷字典的一個方法,把字典中每對key和value組成一個元組,並把這些元組放在一個相似列表的dict_items中返回。
6)keys(self):遍歷字典鍵keys的一個方法,返回一個相似列表的dict_keys,與items方法用法相同。
7) values(self):遍歷字典值value的一個方法,返回一個相似列表的dict_values,與items方法用法相同。
8)pop(self, k, d=None):彈除並返回字典中鍵爲k的值。
9)popitem(self):從字典中隨機取出一組鍵值,返回一個新的元組。
10)setdefault(self, k, default=None):從字典中獲取鍵爲k的值,當存在k時,功能和get基本一致,當字典中不存在k時,在原字典上添加鍵爲k、值爲default的項,並返回default值。
11)update(self, E=None, **F):給字典新增元素,沒有返回值。用法:dict.update(dict2)。


列表:
索引,切片,加,乘,檢查成員。 一、List寫在方括號之間,元素用逗號隔開。 二、和字符串同樣,list能夠被索引和切片。 三、List可使用+操做符進行拼接。 四、List中的元素是能夠改變的。

1)append(self, p_object):在原有列表最後位置上追加新元素到列表,不生成新的列表。
2)clear(self):清空列表裏面的元素,不生成新列表。
3)copy(self):複製一份列表,至關於一次淺拷貝。
5)extend(self, iterable):把iterable中的每一個元素擴展成列表的元素,iterable能夠是字符串、列表、集合、元組、字典。
6)index(self, value, start=None, stop=None):查找列表中value元素索引位置,start與stop參數是查找起始與結束位置,默認爲None。
7)insert(self, index, p_object):在列表index索引位置插入元素p_object,當index大於列表包含的元素個數時,在最後位置插入元素。
8)pop(self, index=None):從列表中取出index位置的值,index默認爲None,此時彈除並返回列表中最後一個值。
9)remove(self, value):移除列表中第一個出現的value元素,value元素不存在列表中時,則拋出ValueError。
10)reverse(self):反轉列表元素的位置。
11)sort(self, key=None, reverse=False):給列表中的元素排序,改變原列表!reverse默認False(升序)。【而sorted()函數是生成副本】。
12)[start:stop:step]:切片,從列表中取出一部分元素生成一個新列表,start與stop默認爲None,step表示步長值,默認是一個接着一個切取,
若是爲2,則表示進行隔一取一操做。步長值爲正時表示從左向右取,若是爲負,則表示從右向左取。步長值不能爲0。
13)索引[index]:獲取索引位置index的值。


元組:
()元組的元素不能修改。 一、與字符串同樣,元組的元素不能修改。 二、元組也能夠被索引和切片,方法同樣。 三、注意構造包含0或1個元素的元組的特殊語法規則。 四、元組也可使用+操做符進行拼接。

1)count(self, value):統計元組中包含value元素的數量,返回一個int值。
2)index(self, value, start=None, stop=None):索引,查找元組中value元素第一個出現的位置,start與stop參數是查找起始與結束位置,默認爲None。
3)[start:stop:step]:切片操做。


Set(集合):
集合(set)是一個無序不重複元素的序列。 可使用大括號 { } 或者 set() 函數建立集合,注意:建立一個空集合必須用 set() 而不是 { },由於 { } 是用來建立一個空字典。

1)add(self, *args, **kwargs):在集合裏添加一個元素,不生成新的集合。
2)clear(self, *args, **kwargs):清空集合裏面的元素,不生成新的集合。
3)copy(self, *args, **kwargs):淺拷貝集合,返回一個新集合。
4)difference(self, *args, **kwargs):傳入一個或多個參數集合對比,返回一個與參數集合不同元素的集合。
5)discard(self, *args, **kwargs):刪除集合中的某個元素,若是這個元素沒有在集合中,不作操做。
6)isdisjoint(self, *args, **kwargs):對比兩個集合,若空交集則返回True,沒有則返回False。
7)issubset(self, *args, **kwargs):判斷集合的包含關係,是不是參數集合的子集。
8)pop(self, *args, **kwargs):從集合中隨機(因集合無序)彈除並返回一個元素,若是集合爲空,則報TypeError錯誤。
9)remove(self, *args, **kwargs):移除集合中的一個元素,這個元素必須在集合中,若是不在,則報TypeError錯誤。
10)union(self, *args, **kwargs):兩個集合拼接返回一個新集合。
11)update(self, *args, **kwargs):更新集合,添加集合中沒有的新元素,不返回新集合。

23:lambda表達式格式以及應用場景?

匿名函數:爲了解決那些功能很簡單的需求而設計的一句話函數。
函數名 = lambda 參數 :返回值

#參數能夠有多個,用逗號隔開
#匿名函數無論邏輯多複雜,只能寫一行,且邏輯執行結束後的內容就是返回值
#返回值和正常的函數同樣能夠是任意數據類型

lambda 表達式
temp = lambda x,y:x+y
print(temp(4,10))   # 14

可替代:
def foo(x,y):
    return x+y
print(foo(4,10))    # 14

24:pass的做用

pass是空語句,是爲了保持程序結構的完整性。pass 不作任何事情,通常用作佔位語句。

25:*arg和**kwargs做用

*arg 表明位置參數,它會接收任意多個參數並把這些參數做爲元祖傳遞給函數。
**kwargs 表明的關鍵字參數,返回的是字典,位置參數必定要放在關鍵字前面。

26. is和==的區別

a = 'lishi'
str1 = "li"
str2 = "shi"
str3 = str1 + str2
print("a == str3",a == str3)
print("a is str3",a is str3)
print("id(a)",id(a))
print("id(str3)",id(str3))
# a == str3 ,True    ==  ---> 只須要內容相等
# a is str3 ,False   is  ---> 只須要內存地址相等
# id(a) 38565848
# id(str3) 39110280
is 比較的是兩個實例對象是否是徹底相同,它們是否是同一個對象,佔用的內存地址是否相同。
== 比較的是兩個對象的內容是否相等,即內存地址能夠不同,內容同樣就能夠了。默認會調用對象的 __eq__()方法。

27:談談Python的深淺拷貝?以及實現方法和應用場景。

淺拷貝只是增長了一個指針指向一個存在的地址,而深拷貝是增長一個指針而且開闢了新的內存,這個增長的指針指向這個新的內存。採用淺拷貝的狀況,釋放內存,會釋放同一內存,深拷貝就不會出現釋放同一內存的錯誤。

一層的狀況:

import copy
 
# 淺拷貝
li1 = [1, 2, 3]
li2 = li1.copy()
li1.append(4)
print(li1, li2)  # [1, 2, 3, 4] [1, 2, 3]
 
# 深拷貝
li1 = [1, 2, 3]
li2 = copy.deepcopy(li1)
li1.append(4)
print(li1, li2)  # [1, 2, 3, 4] [1, 2, 3]

多層的狀況:

import copy
 
# 淺拷貝 指向共有的地址
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]

28:Python垃圾回收機制?

引用計數

標記清除

分代回收

29:Python的可變類型和不可變類型?

可變數據類型:列表、字典、集合

不可變數據類型:數字、字符串、元組

30:求結果

1)
def a(): return [lambda x:i*x for i in range(4)] b=a() #返回個函數列表
print(b[1](1)) ---- 3 print(type(b),b) ---- print([m(1) for m in a()]) ---- [3,3,3,3] print([i*i for i in [1,2,3]]) ---- [1,4,9] #解釋:   函數返回值爲一個列表表達式,通過4次循環結果爲包含四個lambda函數的列表, 因爲函數未被調用,循環中的i值未被寫入函數,通過屢次替代,循環結束後i值爲3。
請修改a的定義來產生指望的結果(0,2,4,6)。
def a():
    return (lambda x:i*x for i in range(4))         #返回一個生成器表達式
print([m(2) for m in a()])
2)
現有兩個元組(('a'),('b')),(('c'),('d')),請使用python匿名函數生成列表[{'a':'c'},{'b':'d'}] #匿名函數形式: li1=(('a'),('b')) li2=(('c'),('d')) ret=map(lambda n:{n[0]:n[1]},zip(li1,li2)) print(list(ret)) #列表表達式形式: li1=(('a'),('b')) li2=(('c'),('d')) print([{n[0]:n[1]} for n in zip(li1,li2)])

31:求結果

v = dict.fromkeys(['k1', 'k2'], [])
v['k1'].append(666)
print(v)

結果:
{'k1': [666], 'k2': [666]}

解釋:
Python 字典(Dictionary) fromkeys() 函數用於建立一個新字典,以序列seq中元素作字典的鍵,value爲字典全部鍵對應的初始值,默認爲None。

v1 = dict.fromkeys(['k1', 'k2'])
print(v1)  # {'k1': None, 'k2': None}
 
v2 = dict.fromkeys(['k1', 'k2'], [])
print(v2)  # {'k1': [], 'k2': []}

32:列舉常見的內置函數

abs()

返回數字的絕對值。

map()

根據函數對指定序列作映射
map()函數接收兩個參數,一個是函數,一個是可迭代對象,map將傳入的函數依次做用到序列的每一個元素,並把結果做爲新的list返回。

返回值:
  Python2 返回列表
  Python3 返回迭代器

例子1: def mul(x): return x*x n=[1,2,3,4,5] res=list(map(mul,n)) print(res) #[1, 4, 9, 16, 25]

例子2:abs() 返回數字的絕對值
ret = map(abs,[-1,-5,6,-7])
print(list(ret))
# [1, 5, 6, 7]

filter()

filter()函數接收一個函數 f(函數)和一個list(可迭代對象),這個函數 f的做用是對每一個元素進行判斷,返回 True或 False,
filter()根據判斷結果自動過濾掉不符合條件的元素,返回由符合條件元素組成的新list。
# 條件函數
def is_odd(x): return x % 2 == 1 v=list(filter(is_odd, [1, 4, 6, 7, 9, 12, 17])) print(v) #[1, 7, 9, 17]

map與filter總結

filter 與 map 總結
共同點: # 參數: 都是一個函數名 + 可迭代對象 # 返回值: 都是返回可迭代對象 區別: # filter 是作篩選的,結果仍是原來就在可迭代對象中的項 # map 是對可迭代對象中每一項作操做的,結果不必定是原來就在可迭代對象中的

isinstance()、type()

isinstance() 函數來判斷一個對象是不是一個已知的類型,相似 type()。
isinstance() 與 type() 區別:
 type() 不會認爲子類是一種父類類型,不考慮繼承關係。返回對象類型
 isinstance() 會認爲子類是一種父類類型,考慮繼承關係。返回布爾

若是要判斷兩個類型是否相同推薦使用 isinstance()。 # 例
a = 2
print(isinstance(a,int)) # True
print(isinstance(a,str)) # False # type() 與 isinstance() 區別 class A: pass class B(A): pass print("isinstance",isinstance(A(),A)) # isinstance True print("type",type(A()) == A) # type True print('isinstance',isinstance(B(),A) ) # isinstance True print('type',type(B()) == A) # type False

zip()打包函數

zip打包函數,
# 將對象中對應的元素打包成一個個元組,
# 而後返回由這些元組組成的列表迭代器。
# 若是各個迭代器的元素個數不一致,則返回列表長度與最短的對象相同。
print(list(zip([0,1,3],[5,6,7],['a','b'])))
# [(0, 5, 'a'), (1, 6, 'b')]
zip() 函數用於將可迭代的對象做爲參數,將對象中對應的元素打包成一個個元組,而後返回由這些元組組成的列表。
>>>a = [1,2,3]
>>> b = [4,5,6]
>>> c = [4,5,6,7,8]
>>> zipped = zip(a,b)     # 打包爲元組的列表
[(1, 4), (2, 5), (3, 6)]
>>> zip(a,c)              # 元素個數與最短的列表一致
[(1, 4), (2, 5), (3, 6)]
>>> zip(*zipped)          # 與 zip 相反,可理解爲解壓,返回二維矩陣式
[(1, 2, 3), (4, 5, 6)]

reduce()

'''
reduce() 累計函數
reduce() 函數會對參數序列中元素進行累積
函數將一個數據集合(鏈表、元組等)中的全部數據進行下列操做
'''

注意:
Python3已經將reduce() 函數從全局名字空間裏移除了,它如今被放置在 fucntools 模塊裏,若是想要使用它,則須要經過引入 functools 模塊來調用 reduce() 函數:

from functools import reduce
def add(x,y):
    return x + y

print(reduce(add,[1,2,3,4,5]))
#  15

print(reduce(lambda x, y: x+y, [1,2,3,4,5]))  # 15

print(reduce(add,range(1,101)))
#  5050

33:filter、map、reduce的做用?

內置函數:map、reduce、filter的用法和區別

map:根據函數對指定序列作映射

map
參數
接收兩個參數:一個是函數,一個是序列(可迭代對象)
返回值
Python2 返回列表
Python3 返回迭代器

# 例子:
# abs() 函數返回數字的絕對值
# 新的內容的個數等於原內容的個數
# ret = map(abs,[-1,-5,6,-7])
# print(list(ret))
# [1, 5, 6, 7]

filter:過濾函數 新的內容少於等於原內容的時候。才能使用filter

filter() 函數用於過濾序列,過濾不符合條件的元素,返回由符合條件元素組成的心列表

參數:
function  函數
iterable  可迭代對象
返回值:
返回列表

# 篩選大於10的數
def is_odd(x):
    if x>10:
        return True

ret = filter(is_odd,[1,4,5,7,8,9,76])  # 爲迭代器
print(list(ret))
# [76]

reduce:對於序列內全部元素進行累計操做

'''
reduce()  函數
reduce() 函數會對參數序列中元素進行累積
函數將一個數據集合(鏈表、元組等)中的全部數據進行下列操做
'''

from functools import reduce
def add(x,y):
    return x + y

print(reduce(add,[1,2,3,4,5]))
#  15

print(reduce(lambda x, y: x+y, [1,2,3,4,5]))  # 15

print(reduce(add,range(1,101)))
#  505

34:一行代碼實現9*9乘法表

multi = '\n'.join([' '.join(['%s*%s=%2s' % (j, i, i * j) for j in range(1, i + 1)]) for i in range(1, 10)])
print(multi)
提示:核心是兩層嵌套列表生成式--> [[... for ...] for ...],而後用空格去拼接內層列表元素,再用換行去拼接外層列表元素。

35:如何安裝第三方模塊?以及用過哪些第三方模塊?

1:pip包管理器
2:源碼下載
    -下載
    -解壓
-python setup.py build
-python setup.py install

用過的第三方模塊:pymysql,BeautifulSoup,SQLAlchemy,Scrapy,Django,memcached等。

36:經常使用內置模塊都有那些?

re,os,sys,json,time,datetime,random,logging等。

37:re的match和search區別?

re.match 嘗試從字符串的起始位置匹配一個模式,若是不是起始位置匹配成功的話,match()就返回none。

re.search 掃描整個字符串並返回第一個成功的匹配。

38:什麼是正則的貪婪匹配?

匹配一個字符串沒有節制,能匹配多少就去匹配多少,知道沒有匹配的爲止。

39:求結果

a. [ i % 2 for i in range(10) ]

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([ 10 % 2])   # [0]
# %是個取餘數運算符。

b. ( i % 2 for i in range(10) )

print(( i % 2 for i in range(10) ))
#  <generator object <genexpr> at 0x00000000020CEEB8> 生成器
# 在Python中,有一種自定義迭代器的方式,稱爲生成器(Generator)。
# 定義生成器的兩種方式:
# 1.建立一個generator,只要把一個列表生成式的[]改爲(),就建立了一個generator:
# generator保存的是算法,每次調用next(),就計算出下一個元素的值,直到計算到最後一個元素,
沒有更多的元素時,拋出StopIteration的錯誤。 # 2.定義generator的另外一種方法。若是一個函數定義中包含yield關鍵字,那麼這個函數就再也不是一個普通函數,
而是一個generator

40:求結果

a. 1 or 2
b. 1 and 2
c. 1 < (2==2)
d. 1 < 2 == 2

>>> 1 or 2
1
>>> 1 and 2
2
>>> 1 < (2==2)
False
>>> 1 < 2 == 2
True

 41:def func(a,b=[]) 這種寫法有什什麼坑?

def func(a,b = []):
    b.append(1)
    print(a,b)

func(a=2)
func(2)
func(2)

'''
    2 [1]
    2 [1, 1]
    2 [1, 1, 1]
    函數的默認參數是一個list 當第一次執行的時候實例化了一個list 
    第二次執行仍是用第一次執行的時候實例化的地址存儲 
    因此三次執行的結果就是 [1, 1, 1] 想每次執行只輸出[1] ,默認參數應該設置爲None,而後初始化b=[]
'''

42:如何實現 "1, 2, 3" 變成 ['1', '2', '3']

list("1,2,3".split(','))

43:如何實現[‘1’,’2’,’3’]變成[1,2,3]

[int(x) for x in ['1','2','3']]

44:a = [1,2,3] 和 b = [(1),(2),(3) ] 以及 c = [(1,),(2,),(3,) ] 的區別?

a等於b,a不等於c 

補充:

a=[1,2,3,4,5],b=a和b=a[:],有區別麼?

a = [1,2,3,4,5]
b = a
b1 = a[:]
print(b)    #  [1, 2, 3, 4, 5]

b.append(6)
print("a",a)  # a [1, 2, 3, 4, 5, 6]
print("b",b)  # b [1, 2, 3, 4, 5, 6]  傳遞引用
print("b1",b1) # b1 [1, 2, 3, 4, 5]   拷貝

45:如何用一行代碼生成[1,4,9,16,25,36,49,64,81,100]

[i*i for i in range(1,11)]

46:一行代碼實現刪除列表中重複的值

list(set([1, 2, 3, 4, 45, 1, 2, 343, 2, 2]))

47:如何在函數中設置一個全局變量

python中的global語句是被用來聲明全局變量的。

x = 2
def func():
    global x  # global用於函數中
    x = 1
    return x
func()
print(x)  # 1

48:logging模塊的做用?以及應用場景?

logging 
模塊定義的函數和類爲應用程序和庫的開發實現了一個靈活的事件日誌系統。

做用:能夠了解程序運行狀況,是否正常
   在程序的出現故障快速定位出錯地方及故障分析

49:請用代碼簡答實現stack

  • Stack() 建立一個新的空棧
  • push(item) 添加一個新的元素item到棧頂
  • pop() 彈出棧頂元素
  • peek() 返回棧頂元素
  • is_empty() 判斷棧是否爲空
  • size() 返回棧的元素個數
# 實現一個棧stack,後進先出

'''
class Stack:
    def __init__(self):
        self.items = []

    def is_empty(self):
        # 判斷是否爲空
        return self.items == []

    def push(self,item):
        # 加入元素
        self.items.append(item)

    def pop(self):
        # 彈出元素
        return self.items.pop()

    def peek(self):
        # 返回棧頂元素
        return self.items[len(self.items)-1]

    def size(self):
        # 返回棧的大小
        return len(self.items)

if __name__ == "__main__":
    stack = Stack()
    stack.push("H")
    stack.push("E")
    stack.push("L")
    print(stack.size())  # 3
    print(stack.peek())  # L 
    print(stack.pop())   # L
    print(stack.pop())   # E
    print(stack.pop())   # H
'''

50:經常使用字符串格式化哪幾種?

1.佔位符%

%d 表示那個位置是整數;%f 表示浮點數;%s 表示字符串。

print('Hello,%s' % 'Python')
print('Hello,%d%s%.2f' % (666, 'Python', 9.99)) # 打印:Hello,666Python10.00

2.format

print('{k} is {v}'.format(k='python', v='easy'))  # 經過關鍵字
print('{0} is {1}'.format('python', 'easy'))      # 經過關鍵字

51:簡述 生成器、迭代器、可迭代對象 以及應用場景?

迭代器

含有__iter__和__next__方法 (包含__next__方法的可迭代對象就是迭代器)

生成器

包括含有yield這個關鍵字,生成器也是迭代器,調動next把函數變成迭代器。

應用場景:
range/xrange
    - py2:xrange(1000000) 生成器
    - py3:range(1000000)生成器 

- redis獲取值
conn = Redis(...)

    def hscan_iter(self, name, match=None, count=None):
      """
      Make an iterator using the HSCAN command so that the client doesn't
      need to remember the cursor position.

      ``match`` allows for filtering the keys by pattern

      ``count`` allows for hint the minimum number of returns
      """
      cursor = '0'
      while cursor != 0:
        # 去redis中獲取數據:12
        # cursor,下一次取的位置
        # data:本地獲取的12條數數據
        cursor, data = self.hscan(name, cursor=cursor,match=match, count=count)
        for item in data.items():
          yield item

可迭代對象

 一個類內部實現__iter__方法且返回一個迭代器。

裝飾器

 裝飾器:
可以在不修改原函數代碼的基礎上,在執行先後進行定製操做,閉包函數的一種應用。
場景:
   - flask路由系統
   - flask before_request
   - csrf
   - django內置認證
   - django緩存
# 手寫裝飾器;
import functools
def wrapper(func):
   @functools.wraps(func)  #不改變原函數屬性
   def inner(*args, **kwargs):
      執行函數前
      return func(*args, **kwargs)
      執行函數後
   return inner
1. 執行wapper函數,並將被裝飾的函數當作參數。 wapper(index)
2. 將第一步的返回值,從新賦值給  新index =  wapper(老index)
@wrapper    #index=wrapper(index)
def index(x):
   return x+100

調用裝飾器實際上是一個閉包函數,爲其餘函數添加附加功能,不修改被修改的源代碼和不修改被修飾的方式,裝飾器的返回值也是一個函數對象。
好比:插入日誌、性能測試、事物處理、緩存、權限驗證等,有了裝飾器,就能夠抽離出大量與函數功能自己無關的雷同代碼並繼續重用。

 52:用Python實現一個二分查找的函數。

二分查找算法:簡單的說,就是將一個列表先排序好,好比按照從小到大的順序排列好,當給定一個數據,好比3,查找3在列表中的位置時,能夠先找到列表中間的數li[middle]和3進行比較,當它比3小時,那麼3必定是在列表的右邊,反之,則3在列表的左邊,好比它比3小,則下次就能夠只比較[middle+1, end]的數,繼續使用二分法,將它一分爲二,直到找到3這個數返回或者列表所有遍歷完成(3不在列表中) 

優勢:效率高,時間複雜度爲O(logN); 
缺點:數據要是有序的,順序存儲。

li = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
def bin_search(arr, find):
mid = len(arr) // 2
if len(arr) >= 1:
if find < arr[mid]:
bin_search(arr[:mid], find)
elif find > arr[mid]:
bin_search(arr[mid + 1:], find)
else:
# return mid    # 當心這個坑!遞歸中不能用return!!
print(mid)
else:
# return '-1'      # 當心這個坑!遞歸中不能用return!!
print("not found !")

53:談談你對閉包的理解?

ef foo():
    m=3
    n=5
    def bar():
        a=4
        return m+n+a
    return bar
  
>>>bar =  foo()
>>>bar()
12

說明:
bar在foo函數的代碼塊中定義。咱們稱bar是foo的內部函數。
在bar的局部做用域中能夠直接訪問foo局部做用域中定義的m、n變量。
簡單的說,這種內部函數可使用外部函數變量的行爲,就叫閉包。

54:os和sys模塊的做用?

os模塊 負責程序與操做系統的交互,提供了訪問操做系統底層的接口。
sys模塊 負責程序與python解釋器的交互,提供了一系列的函數和變量,用於操控python的運行時環境。

#********************** os內置模塊 **********************#
os.name 查看當前操做系統的名稱。windows平臺下返回"nt",Linux則返回"posix"
os.curdir 等價於".",表示當前目錄
os.pardir 等價於"..",表示上級目錄
os.getcwd() 取當前工做目錄名
os.chdir() 切換工做目錄,至關於shell下的cd
os.chmod() 改變目錄權限
os.rename('oldname', 'newname') 重命名文件
os.walk() 生成目錄樹下的全部文件名
os.mkdir/makedirs('dirname') 建立目錄/多層目錄
os.rmdir/removedirs('dirname') 刪除目錄/多層目錄
os.remove('path/filename') 刪除文件
os.listdir('dirname') 列出指定目錄的文件
os.path.basename('path/filename') 去掉目錄,返回文件名
os.path.dirname('path/filename') 去掉文件名,返回目錄
os.path.join(path1[,path2[,...]]) 將分離的各部分組拼接成一個路徑名
os.path.split('path/filename') 返回(dirname(), basename())元組
os.path.splitext('path/filename') 返回(filename, '.擴展名')元組
os.path.getatime/ctime/mtime() 分別返回最近訪問、建立、修改時間(時間戳)
os.path.getsize('path/filename') 返回文件大小(字符數)
os.path.exists() 是否存在
os.path.isabs() 是否爲絕對路徑
os.path.isdir() 是否爲目錄
os.path.isfile() 是否爲文件

#********************** sys內置模塊 **********************#
sys.argv 命令行參數List,第一個元素是程序自己路徑
sys.hexversion 獲取Python解釋程序的版本值,16進制格式如:0x020403F0
sys.version 獲取Python解釋程序的版本信息
sys.maxsize 最大的Int值
sys.maxunicode 最大的Unicode值
sys.modules 返回系統導入的模塊字段,key是模塊名,value是模塊
sys.path 返回模塊的搜索路徑,初始化時使用'PYTHONPATH'環境變量的值
sys.platform 返回操做系統平臺名稱
sys.exec_prefix 返回平臺獨立的python文件安裝的位置
sys.byteorder 本地字節規則的指示器,big-endian平臺的值是'big',little-endian平臺的值是'little'
sys.copyright 記錄python版權相關的東西
sys.api_version 解釋器的C的API版本
sys.stdin 標準輸入
sys.stdout 標準輸出
sys.stderr 錯誤輸出
sys.modules.keys() 返回全部已經導入的模塊列表
sys.exc_info() 獲取當前正在處理的異常類,exc_type、exc_value、exc_traceback當前處理的異常詳細信息
sys.exit(n) 退出程序,正常退出時exit(0)
sys.exc_clear() 用來清除當前線程所出現的當前的或最近的錯誤信息
sys.stdin input()調用了sys.stdin.read()
sys.stdout write()調用了sys.stdout.write()
sys.stderr

55:如何生成一個隨機數?

import random

print(random.random())          # 用於生成一個0到1的隨機浮點數: 0 <= n < 1.0
print(random.randint(1, 1000))  # 用於生成一個指定範圍內的整數
print(random.uniform(1, 1000)) # 用於生成一個指定範圍內的浮點數

56:如何使用python刪除一個文件?

os.remove(file)  # 刪除文件
os.rmdir(dir)   # 刪除目錄

57:談談你對面向對象的理解

三大特性以及解釋?

面對對象是一種編程思想,以類的眼光來來看待事物的一種方式。將有共同的屬性和方法的事物封裝到同一個類下面。

繼承:將多個類的共同屬性和方法封裝到一個父類下面,而後在用這些類來繼承這個類的屬性和方法。

封裝:將有共同的屬性和方法封裝到同一個類下面。

  • 第一層面:建立類和對象會分別建立兩者的名稱空間,咱們只能用類名.或者obj.的方式去訪問裏面的名字,這自己就是一種封裝;
  • 第二層面:類中把某些屬性和方法隱藏起來(或者說定義成私有的),只在類的內部使用、外部沒法訪問,或者留下少許接口(函數)供外部訪問。

多態:Python天生是支持多態的。指的是基類的同一個方法在不一樣的派生類中有着不一樣的功能(重寫體現了多態)。

58:Python面向對象中的繼承有什麼特色

繼承概念的實現方式主要有2類:直接繼承、接口繼承。

直接繼承是指使用基類的屬性和方法而無需額外編碼的能力;
接口繼承是指僅使用屬性和方法的名稱、可是子類必須提供實現的能力(子類重構父類方法);
python  兩種類:經典類 新式類
python3 新式類 都默認繼承object
python2 經典類和新式類 並存
        class Animal:  經典類 -- 繼承順序 個別使用方法
        class Animal(object):  新式類

繼承分爲單繼承和多繼承
Python是支持多繼承的。
若是沒有指定基類,python的類會默認繼承object類,object是全部python類的基類,它提供了一些常見方法(如__str__)的實現。

補充繼承的應用

一、對象能夠調用本身本類和父類的全部方法和屬性, 先調用本身的 本身沒有才調父類的。誰(對象)調用方法,方法中的self就指向誰

class Foo:
    def __init__(self):
        self.func()

    def func(self):
        print('Foo.func')

class Son(Foo):
    def func(self):
        print('Son.func')

s = Son()
 # Son.func

========================================================
class A:
    def get(self):
        self.say()

    def say(self):
        print('AAAAA')

class B(A):
    def say(self):
        print('BBBBB')

b = B()
b.get()   #輸出結果爲:BBBBB

59:面向對象深度優先和廣度優先是什麼?

Python的類能夠繼承多個類,Python的類若是繼承了多個類,那麼其尋找方法的方式有兩種:
  當類是經典類時,多繼承狀況下,會按照深度優先方式查找  --py2
  當類是新式類時,多繼承狀況下,會按照廣度優先方式查找  --py3
簡單點說就是:經典類是縱向查找,新式類是橫向查找。
經典類和新式類的區別就是,在聲明類的時候,新式類須要加上object關鍵字。在python3中默認全是新式類。

60:面向對象中super的做用?

用於子類繼承父類的方法,會將父類的方法徹底繼承下來。
class Foo():
def bar(self):
print('from parent class.')


class Child(Foo):
def bar(self):
super(Child, self).bar()    # 繼承了父類的方法
print('from child class.')   # 增長了本身的功能


c = Child()
c.bar()

# 結果:
from parent class.
from child class.

61:是否使用過functools中的函數?其做用是什麼?

用於保護裝飾器傳入的函數。

import functools
 
def deco(func):
    @functools.wraps(func)  # 加在最內層函數正上方
    def wrapper(*args, **kwargs):
        return func(*args, **kwargs)
 
    return wrapper
 
 
@deco
def index():
    '''哈哈哈哈'''
    x = 10
    print('from index')
 
 
print(index.__name__)
print(index.__doc__)
 
# 加@functools.wraps
# index
# 哈哈哈哈
 
# 不加@functools.wraps
# wrapper
# None

62:列舉面向對象中帶雙下劃線的特殊方法,如:__new__、__init__

  • __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__:一個類變量 用來限制實例能夠添加的屬性的數量和類型  

    __setitem__,__getitem,__delitem__:

class Foo:
    def __init__(self,name):
        self.name=name

    def __getitem__(self, item):
        print(self.__dict__[item])

    def __setitem__(self, key, value):
        self.__dict__[key]=value
    def __delitem__(self, key):
        print('del obj[key]時,我執行')
        self.__dict__.pop(key)
    def __delattr__(self, item):
        print('del obj.key時,我執行')
        self.__dict__.pop(item)

f1=Foo('sb')
f1['age']=18
f1['age1']=19
del f1.age1
del f1['age']
f1['name']='alex'
print(f1.__dict__)

__get__():調用一個屬性時,觸發
__set__():爲一個屬性賦值時,觸發
__delete__():採用del刪除屬性時,觸發

__setattr__,__delattr__,__getattr__ 

63:如何判斷是函數仍是方法?

看他的調用者是誰,若是是類,就須要傳入一個參數self的值,這時他就是一個函數,

若是調用者是對象,就不須要給self傳入參數值,這時他就是一個方法

print(isinstance(obj.func, FunctionType))   # False

print(isinstance(obj.func, MethodType))    # True

64:靜態方法和類方法區別?

儘管 classmethod 和 staticmethod 很是類似,但在用法上依然有一些明顯的區別。classmethod 必須有一個指向類對象的引用做爲第一個參數cls,而 staticmethod 能夠沒有任何參數。

舉個栗子:

class Num:
    # 普通方法:能用Num調用而不能用實例化對象調用   
    def one():  
        print('1')
 
    # 實例方法:能用實例化對象調用而不能用Num調用
    def two(self):
        print('2')
 
    # 靜態方法:能用Num和實例化對象調用
    @staticmethod 
    def three():  
        print('3')
 
    # 類方法:第一個參數cls長什麼樣不重要,都是指Num類自己,調用時將Num類做爲對象隱式地傳入方法   
    @classmethod 
    def go(cls): 
        cls.three() 
 
Num.one()          #1
#Num.two()         #TypeError: two() missing 1 required positional argument: 'self'
Num.three()        #3
Num.go()           #3
 
i=Num()                
#i.one()           #TypeError: one() takes 0 positional arguments but 1 was given         
i.two()            #2      
i.three()          #3
i.go()             #3 

65:列舉面向對象中的特殊成員以及應用場景

__call__

__new__

__init__

__doc__

__class__

__del__

__dict__

__str__

66:一、二、三、四、5 能組成多少個互不相同且無重複的三位數

60個(A35)。

題意理解:組成後的數值不相同,且組合的三個位數之間數字不重複。

使用python內置的排列組合函數(不放回抽樣排列)

product 笛卡爾積  (有放回抽樣排列)

permutations 排列  (不放回抽樣排列)

combinations 組合,沒有重複  (不放回抽樣組合)

combinations_with_replacement 組合,有重複  (有放回抽樣組合)

import itertools
 
print(len(list(itertools.permutations('12345', 3))))  # 60

67:什麼是反射?以及應⽤用場景?

反射的核心本質就是以字符串的形式去導入個模塊,利用字符串的形式去執行函數。

Django中的CBV就是基於反射實現的。

68:metaclass做用?以及應用場景?

metaclass用來指定類是由誰建立的。

類的metaclass默認是type。咱們也能夠指定類的metaclass值。在python3中:

class MyType(type):    # 傳入type
    def __call__(self, *args, **kwargs):
        return 'MyType'
  
  
class Foo(object, metaclass=MyType):
    def __init__(self):
        return 'init'
  
    def __new__(cls, *args, **kwargs):
        return cls.__init__(cls)
  
    def __call__(self, *args, **kwargs):
        return 'call'
  
  
obj = Foo()
print(obj)  # MyType

69:用盡可能多的方法實現單例模式

1:使用模塊
Python的模塊就是自然的單例模式。
由於模塊在第一次導入時,會生成 .pyc 文件,當第二次導入時,就會直接加載 .pyc 文件,而不會再次執行模塊代碼。
所以,咱們只需把相關的函數和數據定義在一個模塊中,就能夠得到一個單例對象了。
例如:
class Single(object):
    def foo(self):
        pass
single = Single()    #  實例好一個對象
將上面代碼保存在文件test.py,要使用時,直接在其餘文件中導入此文件中的對象,這個對象就是單例模式的對象. 如:from test import single

2:使用裝飾器
def single(cls):
_instance = {}
def _singlewrap(*args, **kwargs):
if cls not in _instance:
_instance[cls] = cls(*args, **kwargs)
return _instance[cls]
return _singlewrap

@single
class A(object):

def __init__(self, x=0):
self.x = x

a1 = A(1)
a2 = A(2)
print(a1 == a2) # True

3:基於__new__方法(推薦)
當咱們實例化一個對象時,是先執行了類的__new__方法,咱們沒寫時,默認調用object.__new__,實例化對象;而後再執行類的__init__方法,對這個對象進行初始化,全部咱們能夠基於這個,實現單例模式。
例:

class Person(object):
  def __init__(self, name, age):
    self.name = name
    self.age = age

  def __new__(cls, *args, **kwargs):
    if not hasattr(cls,'instance'):
      cls.instance = super().__new__(cls)
    return cls.instance

a = Person('p1',21)
b = Person('p2',22)
print(a == b, a.name == b.name)
# 這裏的打印結果都是True,可見 a 和 b 都是同一個實例(實例 b 覆蓋了實例 a)。

# 單例做用:
  #第1、控制資源的使用,經過線程同步來控制資源的併發訪問;
  #第2、控制實例產生的數量,達到節約資源的目的;
  #第3、做爲通訊媒介使用,也就是數據共享。好比,數據庫鏈接池的設計通常採用單例模式,數據庫鏈接是一種數據庫資源。

# 應用場景:

  • Python的logger就是一個單例模式,用以日誌記錄
  • 線程池、數據庫鏈接池等資源池通常也用單例模式
  • Windows的資源管理器是一個單例模式
  • 網站計數器

70:裝飾器器的寫法以及應用場景

含義:裝飾器本質就是函數,爲其餘函數添加附加功能。

原則:

不修改被修飾函數的代碼;

不修改被修飾函數的調用方式。

應用場景:

無參裝飾器在用戶登陸認證中常見

有參裝飾器在flask的路由系統中見到過

import functools
def wrapper(func):
    @functools.wraps(func)
    def inner(*args, **kwargs):
        print('我是裝飾器')
        return func
  return inner

@wrapper
def index():
    print('我是被裝飾函數')
    return None

# 應用場景 - 高階函數 - 閉包

71:異常處理寫法以及如何主動拋出異常(應用場景)

# 捕獲異常
def temp_convert(var):
    try:
        return int(var)
    except ValueError as Argument:
        print ("參數沒有包含數字%s"%Argument)

# 調用函數
temp_convert("xyz")
# 以10爲基數的int()的無效文字:「xyz」

---------------------------------------------------------------------------- # raise語法 #raise [Exception(args [,traceback])] # 語句中Exception是異常的類型,args是自已提供的異常參數。 class Networkerror(RuntimeError): def __init__(self, arg): self.args = arg try: raise Networkerror("Bad hostname") except Networkerror as e: print(e.args)

72:什麼是面向對象的mro

mro就是方法解析順序,表明了類繼承的順序。經典類在多重繼承時採用深度優先原則,而新式類是採用廣度優先的原則。

73:isinstance做用以及應用場景?

isinstance(對象,類)  判斷這個對象是否是這個類或者這個類的子類的實例。

# 判斷a 屬不屬於A這個類(能夠判斷到祖宗類)
class A:
    pass

class B(A):
    pass
a = A() b = B() print(isinstance(b,A)) # ===> True 判斷到祖宗類 # 任何與object都是True,內部都繼承object class A:pass a = A() # 實例化 print(isinstance(a,object)) # True

應用場景:rest framework 認證的流程

scrapy-redis

74:寫代碼並實現

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]

75:json序列化時,能夠處理的數據類型有哪些?如何定製支持datetime類型?

支持幾乎除了集合和日期以外的Python對象。

# json模塊不支持datetime序列化,須要自定義格式類

class
ComplexEncoder(json.JSONEncoder):    # 繼承JSONEncoder def default(self, obj):           # 重寫方法 if isinstance(obj, datetime): return obj.strftime('%Y-%m-%d %H:%M:%S') elif isinstance(obj, date): return obj.strftime('%Y-%m-%d') else: return super().default(self, obj)  # 返回父類方法 print(json.dumps({'now': datetime.now()}, cls=ComplexEncoder))

76:json序列化時,默認遇到中文會轉換成unicode,若是想要保留中文怎麼辦?

 在 dumps 函數中添加參數 ensure_ascii=False 便可解決。

77:什麼是斷言?應用場景?

語法:assert '條件', '提示'
其中,若"條件"爲真,程序繼續執行;若"條件"爲假,程序終止,並給出"提示"。

用於程序的調試。

78:有用過with語句嗎?它的好處是什麼?

上下文管理器:在正常處理系統資源(文件、線程鎖和鏈接)以前須要先執行一些準備動做,及其以後須要繼續執行一些收尾動做。
例如:當須要操做文件或數據庫的時候,首先須要獲取文件句柄或者數據庫鏈接對象,當執行完相應的操做後,須要執行釋放文件句柄或者關閉數據庫鏈接的動做。
又如,當多線程程序須要訪問臨界資源的時候,線程首先須要獲取互斥鎖,當執行完成並準備退出臨界區的時候,須要釋放互斥鎖。

79:使用代碼實現查看列舉目錄下的全部文件

os.listdir()  ----列出當前目錄和文件

os.walk()   ----遞歸列出全部文件

80:簡述 yield 和 yield from 關鍵字

yield 用於生成器;
yield from 用於協程。
 
來自轉載,有較大改動。
相關文章
相關標籤/搜索