Python面試題解析之Python基礎篇

python面試題解析(python基礎篇80題)

  1. 答:出於編程的喜好,以及行業自己的前瞻性,創造性,優越性,越是綜合的科目越能檢驗一我的的能力,喜歡這種有挑戰的事情。
  2. 答:跟隨老師學習,以及本身查詢資料,結合實戰,進行輸入輸出以及糾正。
  3. 答:python是強類型加動態語言,自帶有豐富的庫,能夠進行直接調用,無需重複造輪子,缺點是運行相同的程序,速度遠慢於其它類型語言。
  4. 答:編譯型語言是指在運行前先由編譯器將高級語言代碼編譯爲對應機器的cpu彙編指令集,再由彙編器彙編成目標機器碼,生成可執行文件,而後最後運行生成的可執行文件。解釋型在運行時由翻譯器將高級語言代碼翻譯成易於執行的中間代碼,並由解釋器逐一將該中間代碼解釋成機器碼並執行。

  5.答:Cpython,由C語言開發,在命令行下運行python就是啓動Cpython。java

Ipython,基於Cpython之上的一個交互性解釋器,執行方式與Cpython相同。python

PyPy,以執行速度爲目標的解釋器,採用JIT技術,對python代碼進行動態編譯,絕大多數代碼能夠在PyPy下運行。面試

Jpython,運行在java平臺的python解釋器,能夠直接把python代碼編譯成java字節碼執行。正則表達式

  6.答:8位(bit)=1個字節(byte),位是計算機內部數據存儲的最小單位,字節是計算機中數據處理的基本單位,計算機中以字節位單位存儲和解釋信息,規定一個字節由8個二進制位構成。redis

  7.答:8bit = 1byte =1/1024kb = 1/ 1024^2mb = 1/1024^3GB算法

  8.答:縮進使用4個空格,或者IDE中以TAB鍵當作4個空格。django

全部行限制爲最多79個字符編程

兩個空白行圍繞頂層函數和類定義json

核心代碼應始終使用UTF-8,全部標識符使用純ascii標識符,而且應儘量使用英文單詞。flask

Import接口一般應該分開,導入始終放在文件的頂部,緊跟在任何模塊註釋和文檔字符串以後,模塊全局變量和常量以前。

  9.答:

v = int('0b1111011', 2)
print(v)

v1 = bin(18)
print(v1)
v2 = int('011', 8)
print(v2)
v3 = oct(30)
print(v3)
v4 = int('0x12', 16)
print(v4)
print(hex(87))

10.答:

a = "10.3.9.12"


def func(ip):
    Iplist = ip.split(".")  # ['10', '3', '9', '12']
    res = " "
    temp = []
    for i in Iplist:  # <class 'str'>
        i = int(i)  # <class 'int'>
        i = bin(i)[2:]  # <class 'str'>
        temp.append(i.rjust(8, "0"))  # 右對齊,向左填充數據
    res = res.join(temp)
    return res


b = "".join([" ".join(str(bin(int(i))[2:]).rjust(8, "0") for i in a.split("."))])
print(func(a))

11. 答:997層

12.答:1(布爾或:若是x是True,它返回x的值,不然它返回y的計算值。)               
3(x and y 布爾"與" - :
若是 x 爲 False,x and y 返回 False,不然它返回 y 的計算值。)              

      0

      1

      1

      False

13.答:ascii編碼是一個字節,unicode一般是2個字節,GBK則是第一個字節是大於127就固定表示這是一個漢字的開始。Utf-8是每次8個位傳輸數據,utf-16 就是每次16個位。

14.      答:機器碼是電腦CPU直接讀取運行的機器指令,運行速度最快,可是很是晦澀難懂,也比較難編寫,通常從業人員接觸不到。

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

15.答: var = 1 if 條件成立else 2

16.答:1. 性能

  - Py3.x性能比Py2.5慢15%,但還有很大的提高空間。

2.編碼

  - Py3.X源碼文件默認使用utf-8編碼

3. 語法

  - 去除print語句

  - 關鍵詞加入as 和with,還有True,False,None

  - 刪除了raw_input,用input代替

  - 新的metaclass語法

4. 字符串和字節串

  - 字符串只有str一種類型

5.數據類型

  - 只有一種整型——int

  - 新增了bytes類型

6.面向對象

  - 容器類和迭代器類被ABCs化,因此cellections模塊裏的類型比Py2.5多了不少

  - 迭代器的next()方法更名爲__next__(),並增長內置函數next(),用以調用迭代器的__next__()方法

 

17.答: b, a = a,b

18.  答:int <= 32 位整數
long > 32 位整數

19. 答:二者的區別是xrange返回的是一個可迭代的對象,range返回的則是一個列表. 同時效率更高,更快。

  - 緣由是實現的時候使用了 yield(此爲python2.x回答,python3已刪除xrange)

20. 答:xreadlines = 返回一個生成器對象,

readlines =  遍歷文件全部行

21.答:

//     alert(new Boolean(0));  //false

//     alert(new Boolean(-0)); // false

//     alert(new Boolean(null)); // false

//     alert(new Boolean(NaN)); // false

//     alert(new Boolean(undefined)); // false

//     alert(new Boolean("undefined")); // true

//     alert(new Boolean("")); // false

//     alert(new Boolean(false)); // false

//     alert(new Boolean("false")); // true

 

22. 答:

      列表:list

    - list.append(obj) # 在列表末尾添加新的對象

    - list.count(obj)  # 統計某個元素在列表中出現的次數

    - list.extend(seq) # 在列表末尾一次性追加另外一個序列中的多個值(用新列表擴展原來的列表)

    - list.index(obj)  # 從列表中找出某個值第一個匹配項的索引位置

    - list.insert(index, obj)# 將對象插入列表

    - list.pop(obj=list[-1]) # 移除列表中的一個元素(默認最後一個元素),而且返回該元素的值

    - list.remove(obj) # 移除列表中某個值的第一個匹配項

    - list.reverse()   # 反向列表中元素

    - list.sort([func])# 對原列表進行排序

    - list.clear()     # 清空列表

    - list.copy()      # 複製列表

字典:dict

    - popitem()    # 隨機返回並刪除字典中的一對鍵和值(通常刪除末尾對)。

    - key in dict  # 若是鍵在字典dict裏返回true,不然返回false

    - radiansdict.copy()   # 返回一個字典的淺複製

    - radiansdict.keys()   # 以列表返回一個字典全部的鍵

    - radiansdict.items()  # 以列表返回可遍歷的(鍵, 值) 元組數組

    - radiansdict.clear()  # 刪除字典內全部元素

    - radiansdict.values() # 以列表返回字典中的全部值

    - radiansdict.fromkeys()    # 建立一個新字典,以序列seq中元素作字典的鍵,val爲字典全部鍵對應的初始值

    - radiansdict.update(dict2) # 把字典dict2的鍵/值對更新到dict裏

    - radiansdict.get(key, default=None)        # 返回指定鍵的值,若是值不在字典中返回default值

    - radiansdict.setdefault(key, default=None) # 和get()相似, 但若是鍵不存在於字典中,將會添加鍵並將值設爲default

    - pop(key[,default])   # 刪除字典給定鍵 key 所對應的值,返回值爲被刪除的值。key值必須給出。不然,返回default值。

字符串:str

    - upper()      # 轉換字符串中的小寫字母爲大寫。

    - title()      # 返回"標題化"的字符串,就是說全部單詞都是以大寫開始,其他字母均爲小寫(見 istitle())。

    - lower()      # 轉換字符串中全部大寫字符爲小寫。

    - rstrip()     # 刪除字符串字符串末尾的空格.

    - lstrip()     # 截掉字符串左邊的空格或指定字符。

    - max(str)     # 返回字符串 str 中最大的字母。

    - min(str)     # 返回字符串 str 中最小的字母。

    - join(seq)    # 以指定字符串做爲分隔符,將 seq 中全部的元素(的字符串表示)合併爲一個新的字符串

     ...

    MySlef

整數:int

    - bit_length()  # 查詢以二進制表示一個數字的值所需的位數

    - int.from_bytes(bytes,byteorder)  # 返回給定字節數組所表示的整數。

    - int.to_bytes(length,byteorder)   # 返回表示整數的字節數組。

元組:tuple

    - len(tuple) # 計算元組元素個數。

    - max(tuple) # 返回元組中元素最大值。

    - min(tuple) # 返回元組中元素最小值。

    - tuple(seq) # 將列表轉換爲元組。

集合:set

    - set1 = set({1, 2, 'barry'}) # 建立集合

    - set2 = {1, 2, 'barry'}      # 建立集合

    - add  # 將元素添加到集合中。若是元素已經存在,這不起做用。

    - del set1  # 刪除集合- update # 迭代增長

    - clear  # 刪除此集合中的全部元素

    - remove # 刪除一個元素

    - pop    # 隨機刪除一個元素

    - issubset    # 子集

    - issuperset  # 超集

    - union  # 並集。(| 或者 union)

    - difference # 差集。(- 或者 difference)

    - intersection  # 交集。(&  或者 intersection)

    - isdisjoint    # 若是兩個集合有一個空交點,則返回True

    - intersection_update  # 用它本身和另外一個交集更新一個集合。

    - difference_update  # 刪除另外一個集合中本集合所擁有的全部元素

    - symmetric_difference  # 反交集。(^ 或者 symmetric_difference)

浮點:float

    - is_integer # 若是浮點數是整數,則返回True

collections:Python內建的一個集合模塊,提供了許多有用的集合類。

    - Counter     # 是一個簡單的計數器,例如,統計字符出現的個數:

    - OrderedDict # 能夠實現一個FIFO(先進先出)的dict,當容量超出限制時,先刪除最先添加的Key:

    - deque       # 是爲了高效實現插入和刪除操做的雙向列表,適合用於隊列和棧:

    - defaultdict # 使用dict時,若是引用的Key不存在,就會拋出KeyError。若是但願key不存在時,返回一個默認值,就能夠用defaultdict:

 

23. 答:

my_lambda = lambda arg : arg + 1

匿名函數主要是和其它函數搭配使用,不須要顯示指定函數名。

 

24. 答:

- 1. 不作任何事情,通常用作佔位語句。

 - 2. pass是空語句,是爲了保持程序結構的完整性。

25. 答:

位置參數(positional argument)

關鍵詞參數(keyword argument)

  - *args表示任何多個無名參數,它本質是一個 tuple ;

  - **kwargs表示關鍵字參數,它本質上是一個 dict ;

  - 而且同時使用*args和**kwargs時,必須*args參數列要在**kwargs前。

26. 答:

- is 比較的是兩個實例對象是否是徹底相同,它們是否是同一個對象,佔用的內存地址是否相同。萊布尼茨說過:「世界上沒有兩片徹底相同的葉子」,這個is正是這樣的比較,

比較是否是同一片葉子(即比較的id是否相同,這id相似於人的身份證標識)。

  - == 比較的是兩個對象的內容是否相等,即內存地址能夠不同,內容同樣就能夠了。這裏比較的並不是是同一片葉子,可能葉子的種類或者脈絡相同就能夠了。

       默認會調用對象的 __eq__()方法。

27.答:淺拷貝:只拷貝父對象,不會拷貝對象的內部的子對象(父對象不一樣,子對象進行引用,ID相同)深拷貝:拷貝對象及其子對象(父, 子對象不一樣) 因爲深拷貝須要維護一個memo 用於記錄已經拷貝的對象,因此這也是它比較慢的緣由

deepcopy優化版:

class FiveCardStudInfo(roomai.abstract.AbstractInfo):

    public_state = None

    person_state = None

    def __deepcopy__(self, memodict={}):

        info = FiveCardStudInfo()

        info.public_state = self.public_state.__deepcopy__()

        info.public_state = self.person_state.__deepcopy__()

        return info

 

 

28. 答:

引用計數

原理:當一個對象的引用被建立或者複製時,對象的引用計數加1;當一個對象的引用被銷燬時,對象的引用計數減1,當對象的引用計數減小爲0時,就意味着對象已經再沒有被使用了,能夠將其內存釋放掉。

優勢:引用計數有一個很大的優勢,即實時性,任何內存,一旦沒有指向它的引用,就會被當即回收,而其餘的垃圾收集技術必須在某種特殊條件下才能進行無效內存的回收。

缺點:可是它也有弱點,引用計數機制所帶來的維護引用計數的額外操做與Python運行中所進行的內存分配和釋放,引用賦值的次數是成正比的,這顯然比其它那些垃圾收集技術所帶來的額外操做只是與待回收的內存數量有關的效率要低。同時,引用技術還存在另一個很大的問題-循環引用,由於對象之間相互引用,每一個對象的引用都不會爲0,因此這些對象所佔用的內存始終都不會被釋放掉。以下:

a = []

b = []

a.append(b)

b.append(a)

print a

[[[…]]]

print b

[[[…]]]

標記-清除

標記-清除只關注那些可能會產生循環引用的對象,顯然,像是PyIntObject、PyStringObject這些不可變對象是不可能產生循環引用的,由於它們內部不可能持有其它對象的引用。Python中的循環引用老是發生在container對象之間,也就是可以在內部持有其它對象的對象,好比list、dict、class等等。這也使得該方法帶來的開銷只依賴於container對象的的數量 

原理:1. 尋找跟對象(root object)的集合做爲垃圾檢測動做的起點,跟對象也就是一些全局引用和函數棧中的引用,這些引用所指向的對象是不可被刪除的;2. 從root object集合出發,沿着root object集合中的每個引用,若是可以到達某個對象,則說明這個對象是可達的,那麼就不會被刪除,這個過程就是垃圾檢測階段;3. 當檢測階段結束之後,全部的對象就分紅可達和不可達兩部分,全部的可達對象都進行保留,其它的不可達對象所佔用的內存將會被回收,這就是垃圾回收階段。(底層採用的是鏈表將這些集合的對象鏈接在一塊兒)

缺點:標記和清除的過程效率不高。

分代回收

原理:將系統中的全部內存塊根據其存活時間劃分爲不一樣的集合,每個集合就成爲一個「代」,Python默認定義了三代對象集合,垃圾收集的頻率隨着「代」的存活時間的增大而減少。也就是說,活得越長的對象,就越不多是垃圾,就應該減小對它的垃圾收集頻率。那麼如何來衡量這個存活時間:一般是利用幾回垃圾收集動做來衡量,若是一個對象通過的垃圾收集次數越多,能夠得出:該對象存活時間就越長。

 

 

29. 答:可變:

  - list,  - dict

不可變:

  -str,  - int,  - tuple,  - float,

30.答 {'k1': [666], 'k2': [666]}

{'k1': [666, 777], 'k2': [666, 777]}

31.答:[2, 2, 2, 2]

32. 答:map, filter, zip ,isinstance

33. 答:

map:遍歷序列,對序列中每一個元素進行操做,最終獲取新的序列。

  - 每一個元素增長100:

    - li = [11, 22, 33]

    - new_list = map(lambda a: a + 100, li)

  - 兩個列表對應元素相加

    - li = [11, 22, 33]

    - sl = [1, 2, 3, 4]

    - new_list = map(lambda a, b: a + b, li, sl)

 

filter:對於序列中的元素進行篩選,最終獲取符合條件的序列。

  - 獲取列表中大於12的全部元素集合

    - li = [11, 22, 33]

    - new_list = filter(lambda arg: arg > 22, li)

    - # filter第一個參數爲空,將獲取原來序列

 

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

  - 獲取序列全部元素的和

    - li = [11, 22, 33]

    - result = reduce(lambda arg1, arg2: arg1 + arg2, li)

  - # reduce的第一個參數,函數必需要有兩個參數

  - # reduce的第二個參數,要循環的序列

  - # reduce的第三個參數,初始值

 

34. 答:

print('\n'.join([' '.join(['%s*%s=%-2s' % (j, i, i * j) for j in range(1, i + 1)]) for i in range(1, 10)]))

 

35. 答:

      可經過pip install 模塊名來進行聯網安裝。

      第三方模塊,request,django, tornado,flask, redis等等。

 

36.      答:time&datetime模塊,random模塊,os模塊,sys模塊,shutil模塊,json&pickle模塊,shelve模塊,xml模塊,configParser模塊,hashlib模塊,subprocess模塊,logging模塊,re模塊。

 

37. 答:

Match 從頭開始匹配,search匹配包含。

 

38. 答:

      貪婪匹配:正則表達式通常趨向於最大長度匹配,也就是所謂的貪婪匹配

 

39. 答:a.    [0, 1, 0, 1, 0, 1, 0, 1, 0, 1]

      b.<generator object <genexpr> at 0x012C4EA0>

 

40. 答:a. 1

      b.2

      c.False

      d.True

 

41. 答:函數的第二個默認參數是一個list,當第一次執行的時候實例化了一個list,第二次執行仍是用第一次執行的時候實例化的地址存儲,因此三次執行的結果就是 [1, 1, 1] ,想每次執行只輸出[1] ,默認參數應該設置爲None。

 

42. 答:list("1,2,3".split(','))

 

43. 答:[int(x) for x in ['1','2','3']]

 

44.答:列表與列表內包含元祖,以及包含多個元祖。

 

45. 答:[i*i for i in range(1,11)]

 

46. 答:list(set([1, 2, 3, 4, 45, 1, 2, 343, 2, 2]))

 

47. 答:1 聲明法

在文件開頭聲明全局變量variable,

在具體函數中使用該變量時,須要事先聲明 global variable,不然系統將該變量視爲局部變量。

2模塊法(推薦)

把全局變量定義在一個單獨的模塊中:
#gl.py
gl_1 = 'hello'
gl_2 = 'world'

在其它模塊中使用
#a.py
import gl

def hello_world()
    print gl.gl_1, gl.gl_2

#b.py
import gl

def fun1()
    gl.gl_1 = 'Hello'
    gl.gl_2 = 'World'

 

48.答:記錄日誌,而且日誌彙總包含的信息即有正常的程序訪問日誌,還可能有錯誤,警告等信息輸出,應用場景主要有5個level。

DEBUG,INFO,WARNING,ERROR,CRITICAL。

 

49. 答:

1. Stack() 建立一個新的空棧

2. push(item) 添加一個新的元素item到棧頂

3. pop() 彈出棧頂元素

4. peek() 返回棧頂元素

5. is_empty() 判斷棧是否爲空

6. size() 返回棧的元素個數

 

class Stack(object):

    """棧"""

    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("hello")

    stack.push("world")

    stack.push("lcg")

    print stack.size()

    print stack.peek()

    print stack.pop()

    print stack.pop()

    print stack.pop()

 

 

50. 答:

Python的字符串格式化經常使用的有三種

  第一種:最方便的

  缺點:需一個個的格式化

print('hello %s and %s' % ('df', 'another df'))


  第二種:最好用的

  優勢:不須要一個個的格式化,能夠利用字典的方式,縮短期

print('hello %(first)s and %(second)s' % {'first': 'df', 'second': 'another df'})
  第三種:最早進的

    優勢:可讀性強

print('hello {first} and {second}'.format(first='df', second='another df'))

 

51. 答:

容器:

   - 是一系列元素的集合,str、list、set、dict、file、sockets對象均可以看做是容器,容器均可以被迭代(用在for,while等語句中),所以他們被稱爲可迭代對象。

可迭代對象實現了__iter__方法,該方法返回一個迭代器對象。

迭代器:

    - 持有一個內部狀態的字段,用於記錄下次迭代返回值,它實現了__next__和__iter__方法,迭代器不會一次性把全部元素加載到內存,而是須要的時候才生成返回結果。

生成器:

    - 是一種特殊的迭代器,它的返回值不是經過return而是用yield。

裝飾器

- 在不改變原函數代碼的基礎上,在執行先後進行定製操做

52. 答:

li = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]


def search(someone, li):
    l = -1
    h = len(li)

    while l + 1 != h:
        m = int((l + h) / 2)
        if li[m] < someone:
            l = m
        else:
            h = m
    p = h
    if p >= len(li) or li[p] != someone:
        print("元素不存在")
    else:
        str = "元素索引爲%d" % p
        print(str)


search(3, li)  # 元素索引爲2

 

53. 答:def foo():

    m, n=3, 5

    def bar():

        a=4

        return m+n+a

    return bar

>>>bar =  foo()

>>>bar()

 

說明:

bar在foo函數的代碼塊中定義。咱們稱bar是foo的內部函數。

 

在bar的局部做用域中能夠直接訪問foo局部做用域中定義的m、n變量。

簡單的說,這種內部函數可使用外部函數變量的行爲,就叫閉包。

 

- 閉包的意義與應用:延遲計算;

- 閉包的意義:      返回的函數對象,不只僅是一個函數對象,在該函數外還包裹了一層做用域,這使得,該函數不管在何處調用,優先使用本身外層包裹的做用域

 

#應用領域:延遲計算(原來咱們是傳參,如今咱們是包起來)

 

裝飾器就是閉包函數的一種應用場景

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

 

55. 答:使用random模塊能夠很容易生成隨機字符串。

 

56. 答:os 模塊中使用os.remove()來刪除一個文件。

 

57. 答:- 簡單描述:繼承、封裝、多態

- 系統描述:先對代碼進行分類:按屬性進行劃分(file,DB),按功能劃分,將同一類方法分爲一類。將方法中共同的參數封裝到對象中,把共用值封裝到對象中。

面向對象的私有字段:

  - python中一切皆對象

  1. 封裝:對數據的,對對象的封裝。

  2. 繼承:在類的基礎上進行二次開發,經過函數super() 或者"基類名.方法名() "的方式實現這一目的的。

  3. 多態:同一個方法處於不一樣對象中,能夠產生不一樣的結果

- 多態示例

# 鴨子模型

  class A:

      def send(self):

          pass

  class B:

      def send(self):

          pass

      def func(arg):

          arg.send()

          obj = B()

  func(obj)

 

58. 答:繼承指的是類與類之間的關係,是一種「是」什麼的關係,繼承的功能之一就是解決代碼重用問題,python中的繼承可分爲單繼承和多繼承。

 

59. 答:新式類跟經典類的差異主要是如下幾點:

  1. 新式類對象能夠直接經過__class__屬性獲取自身類型:type

  2. 繼承搜索的順序發生了改變,經典類多繼承屬性搜索順序:

      - 先深刻繼承樹左側,再返回,開始找右側;

      - 新式類多繼承屬性搜索順序: 先水平搜索,而後再向上移動。

        ps:(經典類深度優先,新式類廣度優先)

  3. 新式類增長了__slots__內置屬性, 能夠把實例屬性的種類鎖定到__slots__規定的範圍之中。

  4. 新式類增長了__getattribute__方法

 

Python 2.x中默認都是經典類,只有顯式繼承了object纔是新式類

Python 3.x中默認都是新式類,沒必要顯式的繼承object

 

60. 答:子類繼承父類的方法,其繼承順序按照 __mro__來定義

 

61.答:

1. functools模塊的引用

from functools import partial

2. functools模塊的組成

  • partial(func, *args, **keywords)

經過封裝,從新定義已有的函數,如增減參數、設置初始值或改變返回值。
該函數的返回partial對象,其中包含3個只讀屬性:

    • partial.func
    • partial.args
    • partial.keywords
    • @total_ordering

修飾class
實現多個比較操做方法,如__eq__, __lt__等

  • @lru_cache(maxsize=128, typed=False)

修飾方法,從新定義已有的函數
只存在於內存中

  • @singledispatch(default)

修飾方法
將函數轉換爲 single-dispatch generic function

  • @wraps(wrapped_func, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES)

調用update_wrapper()方法的簡便實現

  • update_wrapper(wrapper, wrapped, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES)
  • reduce(function, iterable[, initializer])
  • cmp_to_key(func)

Python的functools模塊用覺得可調用對象(callable objects)定義高階函數或操做。簡單地說,就是基於已有的函數定義新的函數。
所謂高階函數,就是以函數做爲輸入參數,返回也是函數。

 

62. 答:- 雙下劃線:

  1. __getattr__:反射

     應用場景:

       - CBV

       - Django 配置文件

       - wtforms中的Form()實例化中將"_fields中的數據封裝到Form類中"

  2. __mro__:定義解析類繼承的順序

     應用場景:wtforms中 FormMeta中繼承的優先級

  3. __dict__:用來存儲對象屬性的一個字典,其鍵爲屬性名,值爲屬性的值

     - __dict__ 與 dir()的區別:

       1. dir()是一個函數,返回值是list

       2. dir用來尋找一個對象的全部屬性值,包括__dict__中的屬性,__dict__是dir()的子集

  4. __new__ :

     - 當你繼承一些不可變的class時(好比int, str, tuple),提供給你一個自定義這些類的實例化過程的途徑。

     - 實現自定義 metaclass

     應用場景:

       - wtforms 字段實例化時返回:不是StringField,而是UNboundField

       - rest_framework:many=Ture 中的序列化

       - 單例模式

  5. __call__:做用是使實例可以像函數同樣被調用,同時不影響實例自己的生命週期,(__call__()不影響一個實例的構造和析構)

               可是__call__()能夠用來改變實例的內部成員。

     __call__ 與 __init__的區別

     應用場景:

       - FLask 請求的入口app.run()

       - 字段生成標籤時:字段.__str__ ==> 字段.__call__ ==> 插件.__call__

  6. __iter__:

     迭代器爲何要必定實現__iter__方法(爲何要返回自身)

     應用場景:wtforms中BaseForm中循環全部字段時自定義了__iter__方法

 

63. 答:from types import MethodType,FunctionType

 

class func(object):

    def foo(self):

        print(1)

Fun = func()

print(type(func.foo))

>>> <class 'function'>

 

print(type(Fun.foo))

>>> <class 'method'>

 

print(isinstance(func.foo,FunctionType))

>>> True

 

print(isinstance(Fun.foo,MethodType))

>>> True

 

經過類去調用函數foo時,不須要傳self參數。此時foo爲函數

若是經過對象Fun去調用foo時,對象自動傳參self。而foo則是一個方法

 

64. 答:1、先是在語法上面的區別:
一、靜態方法不須要傳入self參數,類成員方法須要傳入表明本類的cls參數;
二、靜態方法是無妨訪問實例變量和類變量的,類成員方法沒法訪問實例變量可是能夠訪問類變量
2、使用的區別:
因爲靜態方法沒法訪問類屬性,實例屬性,至關於一個相對獨立的方法,跟類其實並無什麼關係。這樣說來,靜態方法就是在類的做用域裏的函數而已。
 
65. 答:1.
__doc__
描述類的信息


class Foo(object):
    # 單引號和雙引號均可以 
    """這裏描述類的信息"""

   
def func(self):
        pass


print(Foo.__doc__)


2.
__call__
對象後面加括號,觸發執行


# __call__方法的執行是由對象加括號觸發的,即:對象()或者 類()()
class Foo(object):
    def __call__(self, *args, **kwargs):
        print("running call", args, kwargs)


foo = Foo()
foo(1, 2, 3, name="UserPython")

Foo()(1, 2, 3, name="UserPython")

3.
__dict__
查看類或對象中的全部成員


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


foo = Foo("UserPython", 17)

print(Foo.__dict__)  # 打印類裏的全部屬性,不包括實例屬性
print(foo.__dict__)  # 打印全部實例屬性,不包括類屬性
顯示的結果:

{‘__weakref__‘: < attribute ‘__weakref__‘ of ‘Foo‘ objects >, ‘__init__‘: < function
Foo.__init__
at
0x0000000000BB0730 >, ‘__dict__‘: < attribute ‘__dict__‘ of ‘Foo‘ objects >, ‘__module__‘: ‘__main__‘, ‘__doc__‘: None}
{‘name‘: ‘UserPython‘, ‘age‘: 17}

4.
__str__
若是一個類中定義了__str__方法,那麼在打印對象時,默認輸出該方法的返回值


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

    def __str__(self):
        return "<obj:%s>" % self.name


foo = Foo("UserPython", 17)

print(foo)  # >>><obj:UserPython>
顯示的效果爲:

< obj:UserPython >

5.
__getitem__ 、 __setitem__ 、__delitem__
用於索引操做,如字典。分別表示獲取、設置、刪除數據


class Foo(object):

    def __getitem__(self, key):
        print("__getitem__", key)

    def __setitem__(self, key, value):
        print("__setitem__", key, value)

    def __delitem__(self, key):
        print("__delitem__", key)


foo = Foo()
foo["name"] = "UserPython"  # >>>__setitem__ name UserPython  觸發__setitem__
foo["name"]  # >>>__getitem__ name  觸發__getitem__
del foo["name"]  # >>>__delitem__ name  觸發__delitem__


6.
__new__ 、__metaclass__


class Foo(object):

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


foo = Foo("UserPython")
‘‘‘‘‘
上述代碼中,foo是經過Foo類實例化的對象,其實,不只foo是一個對象,Foo類自己也是一個對象,由於在Python中一切事物都是對象。
若是按照一切事物都是對象的理論:foo對象時經過執行Foo類的構造方法建立,那麼Foo類對象應該也是經過執行某個類的構造方法建立。
‘‘‘

print(type(foo))
print(type(Foo))
# 因此,foo對象是Foo類的一個實例,Foo類對象是type類的一個實例,即:Foo類對象是經過type類的構造方法建立。那麼,建立類就能夠有兩種方式了



# 普通方式
class Foo(object):
    def func(self):
        print("hello UserPython")


# 特殊方式
def func(self):
    print("hello %s" % self.name)


def __init__(self, name, age):  # 構造方法
    self.name = name
    self.age = age


# 建立了一個type類,而後用type類實例化了一個Foo類,因爲Foo自己是一個類,因此Foo又實例化了一個對象foo
Foo = type(‘Foo‘, (object,), {"func": func, "__init__": __init__})

foo = Foo("UserPython", 19)

foo.func()

print(type(Foo))

 

66. 答:5*5*5 ,125個。

 

67. 答:反射主要是指程序能夠訪問,檢測和修改它自己狀態或行爲的一種能力。

      Python面向對象中的反射,四個能夠實現自省的函數。

      Hasattr()

      Getattr()

      Setattr()

      Delattr()

 

68.  答:metaclass是相似建立類的模板,全部的類都是經過他來create的(調用__new__),這使得你能夠自由的控制

建立類的那個過程,實現你所須要的功能。1. 你能夠自由的、動態的修改/增長/刪除類的或者實例中的方法或者屬性

2. 批量的對某些方法使用decorator,而不須要每次都在方法的上面加入@decorator_func

3. 當引入第三方庫的時候,若是該庫某些類須要patch的時候能夠用metaclass

4. 能夠用於序列化(參見yaml這個庫的實現,我沒怎麼仔細看)

5. 提供接口註冊,接口格式檢查等

6. 自動委託(auto delegate)

 

69. 答:1. 文件導入:import方法

# 做爲python的模塊是自然的單例模式

class My_Singleton(object):

    def foo(self):

        pass

my_singleton = My_Singleton()

# to use

from mysingleton import my_singleton

my_singleton.foo()

 

 

2. 使用 __new__ 方法:

--------------------------------(1. # 沒法支持多線程:)------------------------------

class Singleton(object):

    def __init__(self,name):

        self.name = name

    def __new__(cls, *args, **kwargs):

        if not hasattr(Singleton, "instance"):

            Singleton.instance = object.__new__(cls)

        return Singleton.instance

# to use :

obj0 = Singleton("alex")

obj1 = Singleton("alex")

obj2 = Singleton("alex")

 

----------------------------------(2. # 支持多線程:)---------------------------------

import threading

class Singleton(object):

    instance_lock = threading.Lock() # 爲線程加互斥鎖

    def __init__(self):

        pass

    def __new__(cls, *args, **kwargs):

        if not hasattr(Singleton, "instance"):

            with Singleton.instance_lock:

                if not hasattr(Singleton, "instance"):

                    Singleton.instance = object.__new__(cls)

                return Singleton.instance

        return Singleton.instance

def task():

    obj = Singleton()

    print(obj)

for i in range(5):

    t = threading.Thread(target=task)

    t.start()

 

 

3. 使用類實現

--------------------------------(1. # 沒法支持多線程:)------------------------------

import threading

class Singleton(object):

    def __init__(self):

        pass

    @classmethod

    def instance(cls, *args, **kwargs):

        if not hasattr(Singleton, "_instance"):

            Singleton._instance = Singleton(*args, **kwargs)

    return Singleton._instance

# to use

obj = Singleton.instance()

obj2 = Singleton.instance()

print(id(obj), id(obj2))

----------------------------------(2. # 支持多線程:)---------------------------------

import time

import threading

class Singleton(object):

    _instance_lock = threading.Lock()

    def __init__(self):

        time.sleep(1)

    @classmethod

    def instance(cls, *args, **kwargs):

        if not hasattr(Singleton, "_instance"):

            with Singleton._instance_lock:

                if not hasattr(Singleton, "_instance"):

                    Singleton._instance = Singleton(*args, **kwargs)

        return Singleton._instance

# 第一次調用

def task(arg):

    obj = Singleton.instance()

    print(obj)

for i in range(10):

    t = threading.Thread(target=task,args=[i,])

    t.start()

# 第二次調用   

time.sleep(20)

obj = Singleton.instance()

obj2 = Singleton.instance()

print(id(obj, id(obj2)

 

 

4. 基於metaclass

--------------------------------------( 方法一 )--------------------------------------

# 建立對象

class SingletonType(type):

    def __call__(cls, *args, **kwargs):

        obj = super(SingletonType,cls).__call__(*args, **kwargs)   #type類幫建立__new__和__init__並返回

        return obj

class Foo(metaclass=SingletonType):

    def __init__(self,name):

        self.name = name

# to use

obj = Foo("alex")

print(id(obj1))

--------------------------------------( 方法二 )--------------------------------------

 

import threading

class SingletonType(type):

    _instance_lock = threading.Lock()

    def __call__(cls, *args, **kwargs):

        if not hasattr(cls, "_instance"):

            with SingletonType._instance_lock:

                if not hasattr(cls, "_instance"):

                    cls._instance = super(SingletonType,cls).__call__(*args, **kwargs)

        return cls._instance

class Foo(metaclass=SingletonType):

    def __init__(self,name):

        self.name = name

# to use

obj1 = Foo('name')

obj2 = Foo('name')

print(id(obj1),id(obj2))

 

70. 答:def waper(func, x,y):

    print( int(x) + int(y) )

    @functools.wapper               # 保留原函數信息

    def inner(*args, **kwargs):

        """blabla的一些註釋"""

        res = func(*args, **kwargs)

       return res

    return inner

 

@wapper(1,2)

def func(a):

    return a

func(123)     

 

71.答:try expect

 

72. mro即method resolution order,主要用於在多繼承時判斷調的屬性的路徑(來自於哪一個類)。

以前查看了不少資料,說mro是基於深度優先搜索算法的。但不徹底正確在Python2.3以前是基於此算法,但從Python2.3起應用了新算法:C3算法。

 

73.答:介紹:

    函數來判斷一個對象是不是一個已知的類型,相似 type()。

語法:

    isinstance(object, classinfo)

      - object -- 實例對象。

      - classinfo -- 能夠是直接或間接類名、基本類型或者由它們組成的元組。

返回值:

    若是對象的類型與參數二的類型(classinfo)相同則返回 True,不然返回 False。。

應用示例:

    >>>a = 2

    >>> isinstance (a,int)

    True

    >>> isinstance (a,str)

    False

    >>> isinstance (a,(str,int,list))    # 是元組中的一個返回 True

True

 

74.答:

class Solution(object):
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        
if len(nums) <= 1:
            return False
        buff_dict = {}
        for i in range(len(nums)):
            if nums[i] in buff_dict:
                return [buff_dict[nums[i]], i]
            else:
                buff_dict[target - nums[i]] = i

 

75.  答:

自定義時間序列化轉換器

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"}

76. 答:

import json

a=json.dumps({"ddf":"你好"},ensure_ascii=False)

print(a) #{"ddf": "你好"}

77. 答:

Python的assert是用來檢查一個條件,若是它爲真,就不作任何事。若是它爲假,則會拋出AssertError而且包含錯誤信息。

斷言應該用於:

  • 防護型的編程
  • 運行時檢查程序邏輯
  • 檢查約定
  • 程序常量
  • 檢查文檔

78.答:with語句適用於對資源進行訪問的場合,確保無論使用過程當中是否發生異常都會執行必要的「清理」操做,釋放資源,好比文件使用後自動關閉、線程中鎖的自動獲取和釋放等。

 

79. 答:PATH = ‘文件夾路徑’ 
一、list_dir = os.listdir(PATH) 
二、list_dir = next(os.walk(PATH))[1]

 

80. 答:yield是python中定義爲生成器函數,其本質是封裝了  __iter__和__next__方法   的迭代器;

與return返回的區別:return只能返回一次值,函數就終止了,而yield能屢次返回值,每次返回都會將函數暫停,下一次next會從上一次暫停的位置繼續執行;

相關文章
相關標籤/搜索