python外包面試題整理

一、請儘量列舉python列表的成員方法,並給出一下列表操做的答案:
(1) a=[1, 2, 3, 4, 5], html

a[::2] = [1,3,5]
a[-2:] = [4,5]

(2) 一行代碼實現對列表a中的偶數位置的元素進行加3後求和?前端

from functools import reduce
l2 = reduce(lambda x, y: x + y, map(lambda i: l[i] + 3, list(filter(lambda y: y % 2 == 0, range(len(l))))))
l3 = sum(list(map(lambda i: l[i] + 3, list(filter(lambda y: y % 2 == 0, range(len(l)))))))
print(l2)
print(l3)

(3) 將列表a的元素順序打亂,再對a進行排序獲得列表b,而後把a和b按元素順序構造一個字典d。python

from random import shuffle

a = [1, 2, 3, 4, 5]

# 打亂列表a的元素順序
shuffle(a)

# 對a進行排序獲得列表b
b = sorted(a, reverse=True)

# zip 並行迭代,將兩個序列「壓縮」到一塊兒,而後返回一個元組列表,最後,轉化爲字典類型。
d = dict(zip(a, b))

print (d)

(4),List = [-2, 1, 3, -6],如何實現以絕對值大小從小到大將 List 中內容排序。程序員

sorted(list,key=abs)

(5)列表sort方法和sorted的區別是什麼?數組

sort 是list的方法,改變list對象的順序,返回值None
sorted是python的內置方法,適用iterable對象,返回值是新列表,不影響原來的iterable的順序

二、用python實現統計一篇英文文章內每一個單詞的出現頻率,並返回出現頻率最高的前10個單詞及其出現次數,並解答如下問題?(標點符號可忽略)
方法一:緩存

# coding = utf -8
import re
 
with open("this.txt", "r", encoding="utf-8") as fd:
    word_list = []     # 存放全部單詞,所有小寫,並去除,.!等後綴,並去除空格字符串
    word_dict = {}     # 保留{word: count}鍵值對
    for line in fd.readlines():
        for word in line.strip().split(" "):
            word_list.append(re.sub(r"[.|!|,]", "", word.lower()))
    word_sets = list(set(word_list))   # 確保惟一
    word_dict = {word: word_list.count(word) for word in word_sets if word}
result = sorted(word_dict.items(), key=lambda d: d[1], reverse=True)[:10]
print(result)
備註: 遍歷文件,用word_list保留全部的單詞,用word_sets保存惟一的單詞,方便word_dict來做爲鍵。最後對字典排序,取出前10個,很是巧妙.

方法二:藉助collections模塊安全

# coding = utf -8
import re
from collections import Counter
 
with open("this.txt", "r", encoding="utf-8") as fd:
    texts = fd.read()                         # 將文件的內容所有讀取成一個字符串
    count = Counter(re.split(r"\W+", texts))  # 以單詞爲分隔
 
result = count.most_common(10)                # 統計最常使用的前10個
print(result)

(1) 建立文件對象f後,解釋f的readlines和xreadlines方法的區別?網絡

直接輸出後,readlines結尾是\n,返回值readlines返回列表和xreadlines返回生成器

(2) 追加需求:引號內元素須要算做一個單詞,如何實現?數據結構

思路:以"分割,轉換成列表,取其奇數分割,其偶數不作處理

三、簡述python GIL的概念, 以及它對python多線程的影響?編寫一個多線程抓取網頁的程序,並闡明多線程抓取程序是否可比單線程性能有提高,並解釋緣由。多線程

Python語言和GIL沒有半毛錢關係。僅僅是因爲歷史緣由在Cpython虛擬機(解釋器),難以移除GIL。
GIL:全局解釋器鎖。每一個線程在執行的過程都須要先獲取GIL,保證同一時刻只有一個線程能夠執行字節碼。
線程釋放GIL鎖的狀況:
在IO操做等可能會引發阻塞的system call以前,能夠暫時釋放GIL,但在執行完畢後,必須從新獲取GIL
Python 3.x使用計時器(執行時間達到閾值後,當前線程釋放GIL)或Python 2.x,tickets計數達到100

Python使用多進程是能夠利用多核的CPU資源的。

多線程爬取比單線程性能有提高,由於遇到IO阻塞會自動釋放GIL鎖
由於抓取程序涉及到讀取遠程網站頁面的操做,這個操做中從發出請求到得到內容是須要等待IO的;多線程程序能夠利用這個時間進行其餘操做,所以能夠提升效率。

四、用python編寫一個線程安全的單例模式實現。

import threading
import time


class Foo(object):
    _instance = None
    _lock = threading.RLock()

    def __new__(cls, *args, **kwargs):
        if cls._instance:
            return cls._instance
        with cls._lock:
            if not cls._instance:
                cls._instance = object.__new__(cls)
            return cls._instance


def task():
    obj = Foo()
    print(obj)


for i in range(10):
    t = threading.Thread(target=task)
    t.start()

time.sleep(100)
obj = Foo()
View Code

5. 寫一個裝飾器,用於打印函數執行時長。

import time
def timmer(f):  # f = login函數名
    def inner(*args,**kwargs):  # args (2, 3)
        start_time = time.time()
        ret = f(*args,**kwargs)  # login() *(2, 3) 2,3
        end_time = time.time()
        print('此函數的執行時間%s' % (end_time - start_time))
        return ret
    return inner

@timmer  # login = timmer(login)  # inner 此login是新變量
def login(a,b):
    print(a,b)
    time.sleep(0.3)
    print('123456...')
    return 666

print(login(2,3))  # inner(2,3)
View Code

6. Python 中 GIL 是什麼,有什麼做用及影響?線程,進程,協程的區別?

GIL鎖是線程鎖,鎖的是線程,保證同一時刻,一個進程中只有一個線程能夠被CPU調度,不能保證安全
進程:
    # 計算機最小的資源分配單位
    數據隔離,利用多核,數據不安全
    IO密集型/計算密集型 提升併發,資源浪費
線程: 
    # 計算機中最小的CPU調度單位
    數據共享,GIL鎖,數據不安全
    IO密集型,提升併發,多個線程
協程:
    # 線程的一部分,由用戶來調度
    數據共享,數據安全
    IO密集型,提升併發,1個線程
# 併發的本質:切換+保存狀態
計算密集型:進程
IO密集型:線程<攜程​    

進程擁有本身獨立的堆和棧,既不共享堆,亦不共享棧,進程由操做系統調度。

線程擁有本身獨立的棧和共享的堆,共享堆,不共享棧,線程亦由操做系統調度(標準線程是的)。

協程和線程同樣共享堆,不共享棧,協程由程序員在協程的代碼裏顯示調度。
 1、進程多與線程比較

線程是指進程內的一個執行單元,也是進程內的可調度實體。線程與進程的區別:
1) 地址空間:線程是進程內的一個執行單元,進程內至少有一個線程,它們共享進程的地址空間,而進程有本身獨立的地址空間
2) 資源擁有:進程是資源分配和擁有的單位,同一個進程內的線程共享進程的資源
3) 線程是處理器調度的基本單位,但進程不是
4) 兩者都可併發執行

5) 每一個獨立的線程有一個程序運行的入口、順序執行序列和程序的出口,可是線程不可以獨立執行,必須依存在應用程序中,由應用程序提供多個線程執行控制

  2、協程多與線程進行比較

1) 一個線程能夠多個協程,一個進程也能夠單獨擁有多個協程,這樣python中則能使用多核CPU。

2) 線程進程都是同步機制,而協程則是異步

3) 協程能保留上一次調用時的狀態,每次過程重入時,就至關於進入上一次調用的狀態
View Code

五、請回答一下問題:
(1) 闡述一下裝飾器,描述符(property)、元類的概念,並列舉其應用場景;

淺拷貝只是複製了對象的引用地址,兩個對象指向同一個內存地址,因此修改其中任意的值,另外一個值都會隨之變化,這就是淺拷貝
深拷貝:是將對象及值複製過來,兩個對象修改其中任意的值另外一個值不會改變,這就是深拷貝
閉包:內層函數對外層函數非全局變量的引用
裝飾器:裝飾器本質上就是一個函數,在不修改源代碼,調用方法的前提下,用來給其餘函數添加功能的函數。
元類:建立類的就是元類,type是全部類的元類。
描述符:是一種協議,實現了相應的描述符方法便會有相應的描述符行爲,property就是一個特定的描述符類型
裝飾器本質上就是一個python函數,他可讓其餘函數在不須要作任何代碼變更的前提下,增長額外的功能,裝飾器的返回值也是一個函數對象。

裝飾器的應用場景:好比插入日誌,性能測試,事務處理,緩存等等場景。


描述符(__get__,__set__,__delete__)   # 這裏着重描述了python的底層實現原理

  一、 描述符是什麼:描述符本質就是一個新式類,在這個新式類中,至少實現了__get__(),__set__(),__delete__()中的一個,這也被稱爲描述符協議。
    __get__():調用一個屬性時,觸發
    __set__():爲一個屬性賦值時,觸發
    __delete__():採用del刪除屬性時,觸發
描述符是幹什麼的:描述符的做用是用來代理另一個類的屬性的(必須把描述符定義成這個類的類屬性,不能定義到構造函數中)
描述符一般是使用到裝飾器或者元類的大型框架中的一個組件.


元類是類的類,是類的模板

元類是用來控制如何建立類的,正如類是建立對象的模板同樣

元類的主要用途是建立API
View Code

(2) 如何動態獲取和設置對象的屬性。

6.Python中的變量做用域(變量查找順序)。

LEGB
local 局部變量--->enclosed 閉包做用域 ----> Global 全局---->built-in變量

7.下面這段代碼的輸出結果將是什麼?請解釋。

# 1 1 1 繼承自父類的類屬性x,因此都同樣,指向同一塊內存地址
# 1 2 1 更改Child1,Child1的x指向了新的內存地址
# 3 2 3 更改Parent,Parent的x指向了新的內存地址

8,python中如何 動態獲取和設置對象的屬性

if hasattr(Parent,'x'):
    print(getattr(Parent,'x'))
    setattr(Parent,'x',3)
    print(getattr(Parent,'x'))

9.(前端基礎)
(1) 用CSS如何隱藏一個元素

dispaly:none

(2) 一行CSS實現padding上下左右分別爲 1px,2px,3px,4px

padding:1 4 2 3

(3) JavaScript(或jQuery)如何選擇一個id爲main的容器

$('#main')

(4) JavaScript(或jQuery)如何選擇一個class爲menu的容器

$('.menu')

10.Python裏面如何拷貝一個對象?(賦值,淺拷貝,深拷貝的區別)

賦值(=),就是建立了對象的一個新的引用,修改其中任意一個變量都會影響到另外一個。
淺拷貝: 建立一個新的對象,但它包含的是對原始對象中包含項的引用
(若是用引用的方式修改其中一個對象,另一個也會修改改變)
{1,徹底切片方法;2,工廠函數,如list();3,copy模塊的copy()函數}
深拷貝:建立一個新的對象,而且遞歸的複製它所包含的對象
(修改其中一個,另一個不會改變){copy模塊的deep.deepcopy()函數}

11.介紹一下except的用法和做用?

執行try下的語句,若是引起異常,則執行過程會跳到except語句。
對每一個except分支順序嘗試執行,若是引起的異常與except中的異常組匹配,執行相應的語句。
若是全部的except都不匹配,則異常會傳遞到下一個調用本代碼的最高層try代碼中。
try下的語句正常執行,則執行else塊代碼。若是發生異常,就不會執行
若是存在finally語句,最後老是會執行。

12.Python中pass語句的做用是什麼?

pass語句不會執行任何操做,通常做爲佔位符或者建立佔位程序,
whileFalse:pass

13.介紹一下Python下range()函數的用法?

列出一組數據,常常用在for in range()循環中

14.如何用Python來進行查詢和替換一個文本字符串?

可使用re模塊中的sub()函數或者subn()函數來進行查詢和替換,
格式:sub(replacement, string[,count=0])
(replacement是被替換成的文本,
string是須要被替換的文本,
count是一個可選參數,指最大被替換的數量)

15.Python裏面match()和search()的區別?

re模塊中match(pattern,string[,flags]),檢查string的開頭是否與pattern匹配。
re模塊中research(pattern,string[,flags]),在string搜索pattern的第一個匹配值。

16.用Python匹配HTML tag的時候,<.>和<.?>有什麼區別?

術語叫貪婪匹配( <.> )和非貪婪匹配(<.?> )

17.Python裏面如何生成隨機數?

random模塊
隨機整數:random.randint(a,b):
返回隨機整數x,a<=x<=b
random.randrange(start,stop,[,step]):
返回一個範圍在(start,stop,step)之間的隨機整數,不包括結束值。
隨機實數:random.random( ):
返回0到1之間的浮點數
random.uniform(a,b):
返回指定範圍內的浮點數。

18.有沒有一個工具能夠幫助查找python的bug和進行靜態的代碼分析?

PyChecker是一個python代碼的靜態分析工具,
它能夠幫助查找python代碼的bug, 
會對代碼的複雜度和格式提出警告
Pylint是另一個工具能夠進行codingstandard檢查

19.如何在一個function裏面設置一個全局的變量?

解決方法是在function的開始插入一個global聲明:
def f()
global x

20.單引號,雙引號,三引號的區別

單引號和雙引號是等效的,若是要換行,須要符號(),三引號則能夠直接換行,而且能夠包含註釋
若是要表示Let’s go 這個字符串
單引號: s4 = ‘Let\’s go’
雙引號: s5 = 「Let’s go」
s6 = ‘I realy like「python」!’
這就是單引號和雙引號均可以表示字符串的緣由了

21.列舉您使用過的python網絡爬蟲所用到的解析數據包
 

BeautifulSoup、pyquery、Xpath、lxml

22.python經常使用內置函數:

dir(對象名):返回一個列表,列出該對象全部的屬性和方法;
  help(函數名、方法名或對象):查看函數、方法或對象的幫助文檔;
  type(對象名):查看該對象的類型;
  isinstance(對象, 類型):判斷該對象是不是該類型,返回True或False;
  range、input、print就不用多說了。

23. python中的and、or、not邏輯運算符:

andor、not兩邊的值會被放到布爾環境下,做比較
  and運算如x and y:
  x和y都爲True時,那麼返回最後一個值y
  不然返回兩個值中的第一個布爾值爲假的值,從左往右運算
  or運算如x or y:
  只要有一個爲真值,就返回第一個布爾值爲真的值
  若是都爲假,返回最後一個布爾值爲假的值,從左往右運算
  not運算如not x:
  當x的布爾值爲True,返回False
  當x的布爾值爲False,返回True

 24.參數按值傳遞和引用傳遞是怎樣實現的?
 

Python中的一切都是類,全部的變量都是一個對象的引用。引用的值是由函數肯定的,所以沒法被改變。可是若是一個對象是能夠被修改的,你能夠改動對象。

25. python內置的數據類型有哪些?

list: 鏈表, 有序的項目, 經過索引進行查找, 使用方括號"[]"
  dict: 字典, 字典是一組鍵(key)和值(value)的組合, 經過鍵(key)進行查找, 沒有順序, 使用大括號"{}"
  str:字符串,用單或雙引號括起來表示字符串
  tuple: 元組, 元組將多樣的對象集合到一塊兒, 不能修改, 經過索引進行查找, 使用括號"()"
  set: 集合,無序, 元素只出現一次, 使用"set([])",可實現列表快速去重,不過注意返回的是一個集合
  int: 整數,如3
  float:浮點數,如2.3
  complex:複數,如complex(1,2) => 1+2j
  可迭代(遍歷)對象:list、dict、tuple、set、str
  可變類型:list、dict、set,其他爲不可變類型
  list、tuple、str可經過索引獲取當中的元素
  set不支持索引查找,由於數據只出現一次, 它只關心數據是否出現, 不關心其位置。

 26. 在 Python 中如何實現多線程?

一個線程就是一個輕量級進程,多線程能讓咱們一次執行多個線程。咱們都知道,Python 是多線程語言,其內置有多線程工具包。
Python 中的 GIL(全局解釋器鎖)確保一次執行單個線程。一個線程保存 GIL 並在將其傳遞給下個線程以前執行一些操做,這會讓咱們產生並行運行的錯覺。但實際上,只是線程在 CPU 上輪流運行。固然,全部的傳遞會增長程序執行的內存壓力。

27. 解釋一下 Python 中的繼承

當一個類繼承自另外一個類,它就被稱爲一個子類 / 派生類,繼承自父類 / 基類 / 超類。它會繼承 / 獲取全部類成員(屬性和方法)。
繼承能讓咱們從新使用代碼,也能更容易的建立和維護應用。Python 支持以下種類的繼承:
● 單繼承:一個類繼承自單個基類
● 多繼承:一個類繼承自多個基類
● 多級繼承:一個類繼承自單個基類,後者則繼承自另外一個基類
● 分層繼承:多個類繼承自單個基類
● 混合繼承:兩種或多種類型繼承的混合

28, 解釋 Python 中的 help() 和 dir() 函數

Help() 函數是一個內置函數,用於查看函數或模塊用途的詳細說明:
Dir() 函數也是 Python 內置函數,dir() 函數不帶參數時,返回當前範圍內的變量、方法和定義的類型列表;帶參數時,返回參數的屬性、方法列表。

29. 請寫一個 Python 邏輯,計算一個文件中的大寫字母數量

import os

os.chdir('C:\\Users\\lifei\\Desktop')
with open('Today.txt') as today:
    count = 0
for i in today.read():
    if i.isupper():
        count += 1
print(count)

30. 如何以就地操做方式打亂一個列表的元素?

from random import shuffle
mylist = [1,2,34]
shuffle(mylist)
mylist

31. 解釋 Python 中的 join() 和 split() 函數

Join()能讓咱們將指定字符添加至字符串中。

Split() 能讓咱們用指定字符分割字符串。

32. Python 區分大小寫嗎?

若是能區分像 myname 和 Myname 這樣的標識符,那麼它就是區分大小寫的。也就是說它很在意大寫和小寫。

33. Python 中的標識符長度能有多長?

在 Python 中,標識符能夠是任意長度。此外,咱們在命名標識符時還必須遵照如下規則:
只能如下劃線或者 A-Z/a-z 中的字母開頭
其他部分可使用 A-Z/a-z/0-9
區分大小寫
關鍵字不能做爲標識符,

34. 怎麼移除一個字符串中的前導空格?

字符串中的前導空格就是出如今字符串中第一個非空格字符前的空格。咱們使用方法 Istrip() 能夠將它從字符串中移除。
1>>> ' Ayushi '.lstrip()

35. 怎樣將字符串轉換爲小寫?

咱們使用 lower() 方法。
1>>> 'AyuShi'.lower()

36. 在 Python 中有多少種運算符?解釋一下算數運算符。

在 Python 中,咱們有 7 種運算符:算術運算符、關係運算符、賦值運算符、邏輯運算符、位運算符、成員運算符、身份運算符。

37. 在 Python 中如何使用多進制數字?

咱們在 Python 中,除十進制外還可使用二進制、八進制和十六進制。
二進制數字由 0 和 1 組成,咱們使用 0b 或 0B 前綴表示二進制數。
1>>> int(0b1010)
210
2. 使用 bin() 函數將一個數字轉換爲它的二進制形式。
1>>> bin(0xf)
2‘0b1111’
3. 八進制數由數字 0-7 組成,用前綴 0o 或 0O 表示 8 進制數。
1>>> oct(8)
2‘0o10’
4. 十六進數由數字 0-15 組成,用前綴 0x 或者 0X 表示 16 進制數。
1>>> hex(16)
2‘0x103
4>>> hex(15)
5‘0xf’

38. 怎樣獲取字典中全部鍵的列表?

使用 keys() 獲取字典中的全部鍵
1>>> mydict={'a':1,'b':2,'c':3,'e':5}
2>>> mydict.keys()
3dict_keys(['a', 'b', 'c', 'e'])

39. 爲什麼不建議如下劃線做爲標識符的開頭

由於 Python 並無私有變量的概念,因此約定速成如下劃線爲開頭來聲明一個變量爲私有。因此若是你不想讓變量私有,就不要使用下劃線開頭。

40. 怎樣聲明多個變量並賦值?

一共有兩種方式:
1>>> a,b,c=3,4,5 #This assigns 3, 4, and 5 to a, b, and c respectively
2>>> a=b=c=3 #This assigns 3 to a, b, and c

41. 元組的解封裝是什麼?

首先咱們來看解封裝:
1>>> mytuple=3,4,5
2>>> mytuple
3(3, 4, 5)
這將 3,4,5 封裝到元組 mytuple 中。
如今咱們將這些值解封裝到變量 x,y,z 中:
1>>> x,y,z=mytuple
2>>> x+y+z
獲得結果 12.

4二、Python是如何進行內存管理的?

Python GC主要使用引用計數(reference counting)來跟蹤和回收垃圾。在引用計數的基礎上,經過「標記-清除」(mark and sweep)解決容器對象可能產生的循環引用問題,經過「分代回收」(generation collection)以空間換時間的方法提升垃圾回收效率。

4三、垃圾回收機制

當一個對象的引用計數歸零時,它將被垃圾收集機制處理掉。
當兩個對象a和b相互引用時,del語句能夠減小a和b的引用計數,並銷燬用於引用底層對象的名稱。然而因爲每一個對象都包含一個對其餘對象的應用,所以引用計數不會歸零,對象也不會銷燬。(從而致使內存泄露)。爲解決這一問題,解釋器會按期執行一個循環檢測器,搜索不可訪問對象的循環並刪除它們。

4四、引用計數機制

PyObject是每一個對象必有的內容,其中ob_refcnt就是作爲引用計數。當一個對象有新的引用時,它的ob_refcnt就會增長,當引用它的對象被刪除、引用超出做用域或被從新賦值,它的ob_refcnt就會減小.引用計數爲0時,該對象生命就結束了。
優勢:
1. 簡單
2. 實時性
缺點:
1. 維護引用計數消耗資源
2. 循環引用

4五、標記-清除

基本思路是先按需分配,等到沒有空閒內存的時候從寄存器和程序棧上的引用出發,遍歷以對象爲節點、以引用爲邊構成的圖,把全部能夠訪問到的對象打上標記,而後清掃一遍內存空間,把全部沒標記的對象釋放。

4六、分代回收

分代回收的總體思想是:將系統中的全部內存塊根據其存活時間劃分爲不一樣的集合,每一個集合就成爲一個「代」,垃圾收集頻率隨着「代」的存活時間的增大而減少,存活時間一般利用通過幾回垃圾回收來度量。
Python默認定義了三代對象集合,索引數越大,對象存活時間越長。
舉例:
當某些內存塊M通過了3次垃圾收集的清洗以後還存活時,咱們就將內存塊M劃到一個集合A中去,而新分配的內存都劃分到集合B中去。當垃圾收集開始工做時,大多數狀況都只對集合B進行垃圾回收,而對集合A進行垃圾回收要隔至關長一段時間後才進行,這就使得垃圾收集機制須要處理的內存少了,效率天然就提升了。在這個過程當中,集合B中的某些內存塊因爲存活時間長而會被轉移到集合A中,固然,集合A中實際上也存在一些垃圾,這些垃圾的回收會由於這種分代的機制而被延遲。

4七、內存池機制

Python提供了對內存的垃圾收集機制,可是它將不用的內存放到內存池而不是返回給操做系統。
Pymalloc機制。爲了加速Python的執行效率,Python引入了一個內存池機制,用於管理對小塊內存的申請和釋放。
Python中全部小於256個字節的對象都使用pymalloc實現的分配器,而大的對象則使用系統的malloc。
對於Python對象,如整數,浮點數和List,都有其獨立的私有內存池,對象間不共享他們的內存池。

4八、函數參數

普通參數
即在調用函數時必須按照準確的順序來進行參數傳遞。
def fun(name):
print('Hello', name)

fun('World')#Hello World
默認參數
即參數含有默認值,在調用函數時能夠進行參數傳遞,若沒有進行參數傳遞則使用默認值,要注意,默認參數必須在普通參數的右側(不然解釋器沒法解析)
def fun(name, age=1):
print('Hello', name, age, '')

fun('World') # Hello World 1 年
元組參數,即 *args
參數格式化存儲在一個元組中,長度沒有限制,必須位於普通參數和默認參數以後
def fun(name, age=1, *args):
print('Hello', name, age, '') # Hello World 1 年
print(args) # ('I', 'love', 'it')
for i in args:
print(i)

fun('World', 1, 'I', 'love', 'it') 
輸出結果:
I 
love 
it


字典參數,即 **kwargs
參數格式化存儲在一個字典中,必須位於參數列表的最後面
def fun(name, age=1, *args, **kwargs):
print('Hello', name, age, '') # Hello World 1 年
print(args) # ('I', 'love', 'it')
for i in args:
print(i)
print(kwargs) # {'my': 'jack', 'like': 'girl'}
for m in kwargs:
print(m, ':', kwargs[m])

fun('World', 1, 'I', 'love', 'it', my='jack', like='girl')
輸出結果:
Hello World 1 年
('I', 'love', 'it')
I
love
it
{'my': 'jack', 'like': 'girl'}
my : jack
like : girl
View Code

4九、Python裏面如何拷貝一個對象?(賦值,淺拷貝,深拷貝的區別)

賦值(=),就是建立了對象的一個新的引用,修改其中任意一個變量都會影響到另外一個。
淺拷貝:建立一個新的對象,但它包含的是對原始對象中包含項的引用(若是用引用的方式修改其中一個對象,另一個也會修改改變){1,徹底切片方法;2,工廠函數,如list();3,copy模塊的copy()函數}
深拷貝:建立一個新的對象,而且遞歸的複製它所包含的對象(修改其中一個,另一個不會改變){copy模塊的deep.deepcopy()函數}

copy 僅拷貝對象自己,而不拷貝對象中引用的其它對象。
deepcopy 除拷貝對象自己,並且拷貝對象中引用的其它對象。
代碼實例
import copy
a = [1, 2, 3, 4, ['a', 'b']] #原始對象

b = a #賦值,傳對象的引用
c = copy.copy(a) #對象拷貝,淺拷貝
d = copy.deepcopy(a) #對象拷貝,深拷貝

a.append(5) #修改對象a
a[4].append('c') #修改對象a中的['a', 'b']數組對象

print 'a = ', a
print 'b = ', b
print 'c = ', c
print 'd = ', d

輸出結果:
a = [1, 2, 3, 4, ['a', 'b', 'c'], 5]
b = [1, 2, 3, 4, ['a', 'b', 'c'], 5]
c = [1, 2, 3, 4, ['a', 'b', 'c']]
d = [1, 2, 3, 4, ['a', 'b']]

50、Python中重載

函數重載主要是爲了解決兩個問題:
1. 可變參數類型
2. 可變參數個數
解釋一:
那麼對於狀況 1 ,函數功能相同,可是參數類型不一樣,python 如何處理?答案是根本不須要處理,由於 python 能夠接受任何類型的參數,若是函數的功能相同,那麼不一樣的參數類型在 python 中極可能是相同的代碼,沒有必要作成兩個不一樣函數。
那麼對於狀況 2 ,函數功能相同,但參數個數不一樣,python 如何處理?你們知道,答案就是缺乏參數。對那些缺乏的參數設定爲缺乏參數便可解決問題。由於你假設函數功能相同,那麼那些缺乏的參數終歸是須要用的。
鑑於狀況 1 跟 狀況 2 都有了解決方案,python 天然就不須要函數重載了。

解釋二:
簡單來講,Python中爲何不須要重載,重載要解決的是參數類型和參數個數的問題,對於類型,python不像是c語言整型要寫int,字符串要寫str,,,這些python都不須要。

那麼須要解決的就是傳遞參數個數問題,此時python能夠傳遞列表呀,字典呀,可使用*arg和**args呀,因此python根本不須要重載。

5一、Python中單下劃線和雙下劃線

__foo__:一種約定,Python內部的名字,用來區別其餘用戶自定義的命名,以防衝突.
_foo:一種約定,用來指定變量私有.程序員用來指定私有變量的一種方式.
__foo:這個有真正的意義:解析器用_classname__foo來代替這個名字,以區別和其餘類相同的命名.

5二、 __new__和__init__的區別

1. __new__是一個靜態方法,而__init__是一個實例方法.
2. __new__方法會返回一個建立的實例,而__init__什麼都不返回.
3. 只有在__new__返回一個cls的實例時,後面的__init__才能被調用.
4. 當建立一個新實例時調用__new__,初始化一個實例時用__init__.

5三、單例模式

 
 

該模式的主要目的是確保某一個類只有一個實例存在
使用模塊
其實,Python 的模塊就是自然的單例模式,由於模塊在第一次導入時,會生成 .pyc 文件,當第二次導入時,就會直接加載 .pyc 文件,而不會再次執行模塊代碼。所以,咱們只需把相關的函數和數據定義在一個模塊中,就能夠得到一個單例對象了。

 
 

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

 
 

當咱們實現單例時,爲了保證線程安全須要在內部加入鎖,未加鎖部分併發執行,加鎖部分串行執行,速度下降,可是保證了數據安全


import
threading import time class Foo(object): _instance = None _lock = threading.RLock() def __new__(cls, *args, **kwargs): if cls._instance: return cls._instance with cls._lock: if not cls._instance: cls._instance = object.__new__(cls) return cls._instance def task(): obj = Foo() print(obj) for i in range(10): t = threading.Thread(target=task) t.start() time.sleep(100) obj = Foo()

5四、建立字典的方法

直接建立
dict = {'name':'earth', 'port':'80'}
工廠方法
items=[('name','earth'),('port','80')]
dict2=dict(items)
fromkeys()方法
dict1={}.fromkeys(('x','y'),-1)
dict={'x':-1,'y':-1}
dict2={}.fromkeys(('x','y'))
dict2={'x':None, 'y':None}

5五、數組和元組之間的區別是什麼?

相同點
首先,列表與元組都是容器,是一系列的對象;
其次,兩者均可以包含任意類型的元素甚至能夠是一個序列。
不一樣點
列表和元組的「技術差別」是,列表是可變的,而元組是不可變的。

5六、Python都有那些自帶的數據結構?

Python自帶的數據結構分爲可變的和不可變的。
可變的有:
集合
字典
數組
不可變的有:
字符串
元組
數字

5七、推導式

列表(list)推導式
功能:是提供一種方便的列表建立方法,因此,列表解析式返回的是一個列表
例子:
>>> li=[i*2 for i in range(10) if i % 2 == 0]
>>> print li
[0, 4, 8, 12, 16]
列表解析式最擅長的方式就是對整個列表分別作相同的操做,而且返回獲得一個新的列表
字典(dict)推導式

集合(set)推導式
功能:集合推導式跟列表推導式差很少,都是對一個列表的元素所有執行相同的操做,但集合是一種無重複無序的序列
區別:跟列表推到式的區別在於:1.不使用中括號,使用大括號;2.結果中無重複;3.結果是一個set()集合,集合裏面是一個序列
>>> squared={i*2 for i in [1,1,2]}
>>> print squared
set([2, 4])

5八、Python是如何進行類型轉換的?

Python提供了將變量或值從一種類型轉換成另外一種類型的內置函數。好比int函數可以將符合數學格式數字型字符串轉換成整數。不然,返回錯誤信息。

5九、Python是如何被解釋的?

Python是一種解釋性語言,Python解釋器會將源代碼轉換成中間語言,以後再翻譯成機器碼再執行。

60、.Python中的負索引是什麼?

Python中的序列索引能夠是正也能夠是負。若是是正索引,0是序列中的第一個索引,1是第二個索引。若是是負索引,(-1)是最後一個索引而(-2)是倒數第二個索引。

6一、Python的參數傳遞是值傳遞仍是引用傳遞

1).Python的參數傳遞有:
位置參數
默認參數,
可變參數,
關鍵字參數

2).函數的傳值究竟是值傳遞仍是引用傳遞,要分狀況
a.不可變參數用值傳遞:
像整數和字符串這樣的不可變對象,是經過拷貝進行傳遞的,由於你不管如何都不可能在原處改變不可變對象
b.可變參數是用引用傳遞的

好比像列表,字典這樣的對象是經過引用傳遞,和C語言裏面的用指針傳遞數組很類似,可變對象能在函數內部改變.

6二、Xrange和range的區別是什麼?

xrange 函數說明:用法與range徹底相同,所不一樣的是生成的不是一個數組,而是一個生成器。
>>> range(5)
[0, 1, 2, 3, 4]

>>> xrange(5)
xrange(5)
>>> list(xrange(5))
[0, 1, 2, 3, 4]

6三、單引號,雙引號,三引號的區別

1),單引號和雙引號主要用來表示字符串
區別:
若你的字符串裏面自己包含單引號,必須用雙引號
好比:"can't find the log\n"
2).三引號
三單引號:'''python ''',也能夠表示字符串通常用來輸入多行文本,或者用於大段的註釋
三雙引號:"""python""",通常用在類裏面,用來註釋類

6四、類和實例
https://www.cnblogs.com/crazyrunning/p/6945183.html

6五、類變量和實例變量

實例變量是對於每一個實例都獨有的數據,而類變量是該類全部實例共享的屬性和方法。
class Dog:
kind = 'canine' # class variable shared by all instances

def __init__(self, name):
self.name = name # instance variable unique to each instance
類Dog中,類屬性kind爲全部實例所共享;
實例屬性name爲每一個Dog的實例獨有。

6六、類對象和實例對象

類對象
類對象僅支持兩個操做:
實例化;使用instance_name = class_name()的方式實例化,實例化操做建立該類的實例。
屬性引用;使用class_name.attr_name的方式引用類屬性。
實例對象
實例對象是類對象實例化的產物,實例對象僅支持一個操做:
屬性引用;與類對象屬性引用的方式相同,使用instance_name.attr_name的方式。

6七、屬性綁定

咱們說的屬性綁定,首先須要一個可變對象,才能執行綁定操做,使用objname.attr = attr_value的方式,爲對象objname綁定屬性attr。
這分兩種狀況:
若屬性attr已經存在,綁定操做會將屬性名指向新的對象;
若不存在,則爲該對象添加新的屬性,後面就能夠引用新增屬性。
類屬性綁定
類屬性的綁定發生在兩個地方:
類定義時;
運行時任意階段。

在類定義中,類屬性的綁定並無使用objname.attr = attr_value的方式,這是一個特例,實際上是等同於後面使用類名綁定屬性的方式。
由於是動態語言,因此能夠在運行時增長屬性,刪除屬性。
實例屬性綁定
與類屬性綁定相同,實例屬性綁定也發生在兩個地方:
類定義時;
運行時任意階段。

類實例有兩個特殊之處:
__init__在實例化時執行
Python實例調用方法時,會將實例對象做爲第一個參數傳遞
所以,__init__方法中的self就是實例對象自己

6八、屬性引用

類屬性引用
類屬性的引用,確定是須要類對象的,屬性分爲兩種:
數據屬性
函數屬性
實例屬性引用
使用實例對象引用屬性稍微複雜一些,由於實例對象可引用類屬性以及實例屬性。可是實例對象引用屬性時遵循如下規則:
老是先到實例對象中查找屬性,再到類屬性中查找屬性;
屬性綁定語句老是爲實例對象建立新屬性,屬性存在時,更新屬性指向的對象。

6九、Python 中的 is 和 ==

is比較內存地址是否相同,==比較數值是否相同

30、isinstance 和 type 的區別

class A:
pass

class B(A):
pass

isinstance(A(), A) # returns True
type(A()) == A # returns True
isinstance(B(), A) # returns True
type(B()) == A # returns False

區別就是:
type()不會認爲子類是一種父類類型。
isinstance()會認爲子類是一種父類類型。
相關文章
相關標籤/搜索