2019 Python100道 面试 题,你会几道?
0 遇到過(guò)得反爬蟲(chóng)策略以及解決方法?
1.通過(guò)headers反爬蟲(chóng)
2.基于用戶(hù)行為的發(fā)爬蟲(chóng):(同一IP短時(shí)間內(nèi)訪(fǎng)問(wèn)的頻率)
3.動(dòng)態(tài)網(wǎng)頁(yè)反爬蟲(chóng)(通過(guò)ajax請(qǐng)求數(shù)據(jù),或者通過(guò)JavaScript生成)
4.對(duì)部分?jǐn)?shù)據(jù)進(jìn)行加密處理的(數(shù)據(jù)是亂碼)
解決方法:
對(duì)于基本網(wǎng)頁(yè)的抓取可以自定義headers,添加headers的數(shù)據(jù)
使用多個(gè)代理ip進(jìn)行抓取或者設(shè)置抓取的頻率降低一些,
動(dòng)態(tài)網(wǎng)頁(yè)的可以使用selenium + phantomjs 進(jìn)行抓取
對(duì)部分?jǐn)?shù)據(jù)進(jìn)行加密的,可以使用selenium進(jìn)行截圖,使用python自帶的pytesseract庫(kù)進(jìn)行識(shí)別,但是比較慢最直接的方法是找到加密的方法進(jìn)行逆向推理。
1 urllib 和 urllib2 的區(qū)別?
- urllib 和urllib2都是接受URL請(qǐng)求的相關(guān)模塊,但是urllib2可以接受一個(gè)Request類(lèi)的實(shí)例來(lái)設(shè)置URL請(qǐng)求的headers,urllib僅可以接受URL。urllib不可以偽裝你的User-Agent字符串。
- urllib提供urlencode()方法用來(lái)GET查詢(xún)字符串的產(chǎn)生,而urllib2沒(méi)有。這是為何urllib常和urllib2一起使用的原因。
2 列舉網(wǎng)絡(luò)爬蟲(chóng)所用到的網(wǎng)絡(luò)數(shù)據(jù)包,解析包?
- 網(wǎng)絡(luò)數(shù)據(jù)包 urllib、urllib2、requests
- 解析包 re、xpath、beautiful soup、lxml
3 簡(jiǎn)述一下爬蟲(chóng)的步驟?
- 確定需求;
- 確定資源;
- 通過(guò)url獲取網(wǎng)站的返回?cái)?shù)據(jù);
- 定位數(shù)據(jù);
- 存儲(chǔ)數(shù)據(jù)。
4 遇到反爬機(jī)制怎么處理?
反爬機(jī)制:
headers方向
判斷User-Agent、判斷Referer、判斷Cookie。
將瀏覽器的headers信息全部添加進(jìn)去
注意:Accept-Encoding;gzip,deflate需要注釋掉
5 常見(jiàn)的HTTP方法有哪些?
- GET:請(qǐng)求指定的頁(yè)面信息,返回實(shí)體主體;
- HEAD:類(lèi)似于get請(qǐng)求,只不過(guò)返回的響應(yīng)中沒(méi)有具體的內(nèi)容,用于捕獲報(bào)頭;
- POST:向指定資源提交數(shù)據(jù)進(jìn)行處理請(qǐng)求(比如表單提交或者上傳文件),。數(shù)據(jù)被包含在請(qǐng)求體中。
- PUT:從客戶(hù)端向服務(wù)端傳送數(shù)據(jù)取代指定的文檔的內(nèi)容;
- DELETE:請(qǐng)求刪除指定的頁(yè)面;
- CONNNECT:HTTP1.1協(xié)議中預(yù)留給能夠?qū)⑦B接方式改為管道方式的代理服務(wù)器;
- OPTIONS:允許客戶(hù)端查看服務(wù)器的性能;
TRACE:回顯服務(wù)器的請(qǐng)求,主要用于測(cè)試或者診斷。
6 說(shuō)一說(shuō)redis-scrapy中redis的作用?
它是將scrapy框架中Scheduler替換為redis數(shù)據(jù)庫(kù),實(shí)現(xiàn)隊(duì)列管理共享。
優(yōu)點(diǎn):
- 可以充分利用多臺(tái)機(jī)器的帶寬;
- 可以充分利用多臺(tái)機(jī)器的IP地址。
7 遇到的反爬蟲(chóng)策略以及解決方法?
- 通過(guò)headers反爬蟲(chóng):自定義headers,添加網(wǎng)頁(yè)中的headers數(shù)據(jù)。
- 基于用戶(hù)行為的反爬蟲(chóng)(封IP):可以使用多個(gè)代理IP爬取或者將爬取的頻率降低。
- 動(dòng)態(tài)網(wǎng)頁(yè)反爬蟲(chóng)(JS或者Ajax請(qǐng)求數(shù)據(jù)):動(dòng)態(tài)網(wǎng)頁(yè)可以使用 selenium + phantomjs 抓取。
- 對(duì)部分?jǐn)?shù)據(jù)加密處理(數(shù)據(jù)亂碼):找到加密方法進(jìn)行逆向推理。
8 如果讓你來(lái)防范網(wǎng)站爬蟲(chóng),你應(yīng)該怎么來(lái)提高爬取的難度 ?
- 判斷headers的User-Agent;
- 檢測(cè)同一個(gè)IP的訪(fǎng)問(wèn)頻率;
- 數(shù)據(jù)通過(guò)Ajax獲取;
- 爬取行為是對(duì)頁(yè)面的源文件爬取,如果要爬取靜態(tài)網(wǎng)頁(yè)的html代碼,可以使用jquery去模仿寫(xiě)html。
9 scrapy分為幾個(gè)組成部分?分別有什么作用?
分為5個(gè)部分;Spiders(爬蟲(chóng)類(lèi)),Scrapy Engine(引擎),Scheduler(調(diào)度器),Downloader(下載器),Item Pipeline(處理管道)。
- Spiders:開(kāi)發(fā)者自定義的一個(gè)類(lèi),用來(lái)解析網(wǎng)頁(yè)并抓取指定url返回的內(nèi)容。
- Scrapy Engine:控制整個(gè)系統(tǒng)的數(shù)據(jù)處理流程,并進(jìn)行事務(wù)處理的觸發(fā)。
- Scheduler:接收Engine發(fā)出的requests,并將這些requests放入到處理列隊(duì)中,以便之后engine需要時(shí)再提供。
- Download:抓取網(wǎng)頁(yè)信息提供給engine,進(jìn)而轉(zhuǎn)發(fā)至Spiders。
- Item Pipeline:負(fù)責(zé)處理Spiders類(lèi)提取之后的數(shù)據(jù)。
比如清理HTML數(shù)據(jù)、驗(yàn)證爬取的數(shù)據(jù)(檢查item包含某些字段)、查重(并丟棄)、將爬取結(jié)果保存到數(shù)據(jù)庫(kù)中
10 簡(jiǎn)述一下scrapy的基本流程?
scrapy分為9個(gè)步驟:
- Spiders需要初始的start_url或則函數(shù)stsrt_requests,會(huì)在內(nèi)部生成Requests給Engine;
- Engine將requests發(fā)送給Scheduler;
- Engine從Scheduler那獲取requests,交給Download下載;
- 在交給Dowmload過(guò)程中會(huì)經(jīng)過(guò)Downloader Middlewares(經(jīng)過(guò)process_request函數(shù));
- Dowmloader下載頁(yè)面后生成一個(gè)response,這個(gè)response會(huì)傳給Engine,這個(gè)過(guò)程中又經(jīng)過(guò)了Downloader Middlerwares(經(jīng)過(guò)process_request函數(shù)),在傳送中出錯(cuò)的話(huà)經(jīng)過(guò)process_exception函數(shù);
- Engine將從Downloader那傳送過(guò)來(lái)的response發(fā)送給Spiders處理,這個(gè)過(guò)程經(jīng)過(guò)Spiders Middlerwares(經(jīng)過(guò)process_spider_input函數(shù));
- Spiders處理這個(gè)response,返回Requests或者Item兩個(gè)類(lèi)型,傳給Engine,這個(gè)過(guò)程又經(jīng)過(guò)Spiders Middlewares(經(jīng)過(guò)porcess_spider_output函數(shù));
- Engine接收返回的信息,如果使Item,將它傳給Items Pipeline中;如果是Requests,將它傳給Scheduler,繼續(xù)爬蟲(chóng);
- 重復(fù)第三步,直至沒(méi)有任何需要爬取的數(shù)據(jù)
11 python3.5語(yǔ)言中enumerate的意思是
對(duì)于一個(gè)可迭代的(iterable)/可遍歷的對(duì)象(如列表、字符串),enumerate將其組成一個(gè)索引序列,利用它可以同時(shí)獲得索引和值
enumerate多用于在for循環(huán)中得到計(jì)數(shù)
12 你是否了解谷歌的無(wú)頭瀏覽器?
無(wú)頭瀏覽器即headless browser,是一種沒(méi)有界面的瀏覽器。既然是瀏覽器那么瀏覽器該有的東西它都應(yīng)該有,只是看不到界面而已。
Python中selenium模塊中的PhantomJS即為無(wú)界面瀏覽器(無(wú)頭瀏覽器):是基于QtWebkit的無(wú)頭瀏覽器。
13 scrapy和scrapy-redis的區(qū)別?
scrapy是一個(gè)爬蟲(chóng)通用框架,但不支持分布式,scrapy-redis是為了更方便的實(shí)現(xiàn)scrapy分布式爬蟲(chóng),而提供了一些以redis為基礎(chǔ)的組件
為什么會(huì)選擇redis數(shù)據(jù)庫(kù)?
因?yàn)閞edis支持主從同步,而且數(shù)據(jù)都是緩存在內(nèi)存中,所以基于redis的分布式爬蟲(chóng),對(duì)請(qǐng)求和數(shù)據(jù)的高頻讀取效率非常高
什么是主從同步?
在Redis中,用戶(hù)可以通過(guò)執(zhí)行SLAVEOF命令或者設(shè)置slaveof選項(xiàng),讓一個(gè)服務(wù)器去復(fù)制(replicate)另一個(gè)服務(wù)器,我們稱(chēng)呼被復(fù)制的服務(wù)器為主服務(wù)器(master),而對(duì)主服務(wù)器進(jìn)行復(fù)制的服務(wù)器則被稱(chēng)為從服務(wù)器(slave),當(dāng)客戶(hù)端向從服務(wù)器發(fā)送SLAVEOF命令,要求從服務(wù)器復(fù)制主服務(wù)器時(shí),從服務(wù)器首先需要執(zhí)行同步操作,也即是,將從服務(wù)器的數(shù)據(jù)庫(kù)狀態(tài)更新至主服務(wù)器當(dāng)前所處的數(shù)據(jù)庫(kù)狀態(tài)
14 scrapy的優(yōu)缺點(diǎn)?為什么要選擇scrapy框架?
優(yōu)點(diǎn):
采取可讀性更強(qiáng)的xpath代替正則 強(qiáng)大的統(tǒng)計(jì)和log系統(tǒng) 同時(shí)在不同的url上爬行 支持shell方式,方便獨(dú)立調(diào)試 寫(xiě)middleware,方便寫(xiě)一些統(tǒng)一的過(guò)濾器 通過(guò)管道的方式存入數(shù)據(jù)庫(kù)
缺點(diǎn):
基于python爬蟲(chóng)框架,擴(kuò)展性比較差,基于twisted框架,運(yùn)行中exception是不會(huì)干掉reactor,并且異步框架出錯(cuò)后是不會(huì)停掉其他任務(wù)的,數(shù)據(jù)出錯(cuò)后難以察覺(jué)
15 scrapy和requests的使用情況?
requests 是 polling 方式的,會(huì)被網(wǎng)絡(luò)阻塞,不適合爬取大量數(shù)據(jù)
scapy 底層是異步框架 twisted ,并發(fā)是最大優(yōu)勢(shì)
16 描述一下scrapy框架的運(yùn)行機(jī)制?
從start_urls里面獲取第一批url發(fā)送請(qǐng)求,請(qǐng)求由請(qǐng)求引擎給調(diào)度器入請(qǐng)求對(duì)列,獲取完畢后,調(diào)度器將請(qǐng)求對(duì)列交給下載器去獲取請(qǐng)求對(duì)應(yīng)的響應(yīng)資源,并將響應(yīng)交給自己編寫(xiě)的解析方法做提取處理,如果提取出需要的數(shù)據(jù),則交給管道處理,如果提取出url,則繼續(xù)執(zhí)行之前的步驟,直到多列里沒(méi)有請(qǐng)求,程序結(jié)束。
17 寫(xiě)爬蟲(chóng)使用多進(jìn)程好,還是用多線(xiàn)程好?
IO密集型代碼(文件處理、網(wǎng)絡(luò)爬蟲(chóng)等),多線(xiàn)程能夠有效提升效率(單線(xiàn)程下有IO操作會(huì)進(jìn)行IO等待,造成不必要的時(shí)間浪費(fèi),而開(kāi)啟多線(xiàn)程能在線(xiàn)程A等待時(shí),自動(dòng)切換到線(xiàn)程B,可以不浪費(fèi)CPU的資源,從而能提升程序執(zhí)行效率)。在實(shí)際的數(shù)據(jù)采集過(guò)程中,既考慮網(wǎng)速和響應(yīng)的問(wèn)題,也需要考慮自身機(jī)器的硬件情況,來(lái)設(shè)置多進(jìn)程或多線(xiàn)程
18 常見(jiàn)的反爬蟲(chóng)和應(yīng)對(duì)方法?
- 基于用戶(hù)行為,同一個(gè)ip段時(shí)間多次訪(fǎng)問(wèn)同一頁(yè)面 利用代理ip,構(gòu)建ip池
- 請(qǐng)求頭里的user-agent 構(gòu)建user-agent池(操作系統(tǒng)、瀏覽器不同,模擬不同用戶(hù))
- 動(dòng)態(tài)加載(抓到的數(shù)據(jù)和瀏覽器顯示的不一樣),js渲染 模擬ajax請(qǐng)求,返回json形式的數(shù)據(jù)
- selenium / webdriver 模擬瀏覽器加載
- 對(duì)抓到的數(shù)據(jù)進(jìn)行分析
- 加密參數(shù)字段 會(huì)話(huà)跟蹤【cookie】 防盜鏈設(shè)置【Referer
19 分布式爬蟲(chóng)主要解決什么問(wèn)題?
面對(duì)海量待抓取網(wǎng)頁(yè),只有采用分布式架構(gòu),才有可能在較短時(shí)間內(nèi)完成一輪抓取工作。
它的開(kāi)發(fā)效率是比較快而且簡(jiǎn)單的。
20 如何提高爬取效率?
爬蟲(chóng)下載慢主要原因是阻塞等待發(fā)往網(wǎng)站的請(qǐng)求和網(wǎng)站返回
1,采用異步與多線(xiàn)程,擴(kuò)大電腦的cpu利用率;2,采用消息隊(duì)列模式3,提高帶寬
21 說(shuō)說(shuō)什么是爬蟲(chóng)協(xié)議?
Robots協(xié)議(也稱(chēng)為爬蟲(chóng)協(xié)議、爬蟲(chóng)規(guī)則、機(jī)器人協(xié)議等)也就是robots.txt,網(wǎng)站通過(guò)robots協(xié)議告訴搜索引擎哪些頁(yè)面可以抓取,哪些頁(yè)面不能抓取。
Robots協(xié)議是網(wǎng)站國(guó)際互聯(lián)網(wǎng)界通行的道德規(guī)范,其目的是保護(hù)網(wǎng)站數(shù)據(jù)和敏感信息、確保用戶(hù)個(gè)人信息和隱私不被侵犯。因其不是命令,故需要搜索引擎自覺(jué)遵守。
22 如果對(duì)方網(wǎng)站反爬取,封IP了怎么辦?
- 放慢抓取熟速度,減小對(duì)目標(biāo)網(wǎng)站造成的壓力,但是這樣會(huì)減少單位時(shí)間內(nèi)的數(shù)據(jù)抓取量
- 使用代理IP(免費(fèi)的可能不穩(wěn)定,收費(fèi)的可能不劃算)
23 有一個(gè)jsonline格式的文件file
'''
遇到問(wèn)題沒(méi)人解答?小編創(chuàng)建了一個(gè)Python學(xué)習(xí)交流QQ群:857662006 尋找有志同道合的小伙伴,
互幫互助,群里還有不錯(cuò)的視頻學(xué)習(xí)教程和PDF電子書(shū)!
'''
def get_lines():with open('file.txt','rb') as f:return f.readlines()if __name__ == '__main__':for e in get_lines():process(e) # 處理每一行數(shù)據(jù)
現(xiàn)在要處理一個(gè)大小為10G的文件,但是內(nèi)存只有4G,如果在只修改get_lines 函數(shù)而其他代碼保持不變的情況下,應(yīng)該如何實(shí)現(xiàn)?需要考慮的問(wèn)題都有那些?
def get_lines():with open('file.txt','rb') as f:for i in f:yield i
Pandaaaa906提供的方法
from mmap import mmapdef get_lines(fp):with open(fp,"r+") as f:m = mmap(f.fileno(), 0)tmp = 0for i, char in enumerate(m):if char==b"\n":yield m[tmp:i+1].decode()tmp = i+1if __name__=="__main__":for i in get_lines("fp_some_huge_file"):print(i)
要考慮的問(wèn)題有:內(nèi)存只有4G無(wú)法一次性讀入10G文件,需要分批讀入分批讀入數(shù)據(jù)要記錄每次讀入數(shù)據(jù)的位置。分批每次讀取數(shù)據(jù)的大小,太小會(huì)在讀取操作花費(fèi)過(guò)多時(shí)間。
https://stackoverflow.com/questions/30294146/python-fastest-way-to-process-large-file
24 補(bǔ)充缺失的代碼
def print_directory_contents(sPath):
"""
這個(gè)函數(shù)接收文件夾的名稱(chēng)作為輸入?yún)?shù)
返回該文件夾中文件的路徑
以及其包含文件夾中文件的路徑
遇到問(wèn)題沒(méi)人解答?
小編創(chuàng)建了一個(gè)Python學(xué)習(xí)交流QQ群:857662006
尋找有志同道合的小伙伴,
互幫互助,群里還有不錯(cuò)的視頻學(xué)習(xí)教程和PDF電子書(shū)!
"""
import os
for s_child in os.listdir(s_path):s_child_path = os.path.join(s_path, s_child)if os.path.isdir(s_child_path):print_directory_contents(s_child_path)else:print(s_child_path)
25 輸入日期, 判斷這一天是這一年的第幾天?
import datetime
def dayofyear():year = input("請(qǐng)輸入年份: ")month = input("請(qǐng)輸入月份: ")day = input("請(qǐng)輸入天: ")date1 = datetime.date(year=int(year),month=int(month),day=int(day))date2 = datetime.date(year=int(year),month=1,day=1)return (date1-date2).days+1
26 打亂一個(gè)排好序的list對(duì)象alist?
import random
alist = [1,2,3,4,5]
random.shuffle(alist)
print(alist)
27 現(xiàn)有字典 d= {‘a(chǎn)’:24,‘g’:52,‘i’:12,‘k’:33}請(qǐng)按value值進(jìn)行排序?
sorted(d.items(),key=lambda x:x[1])
28 字典推導(dǎo)式
d = {key:value for (key,value) in iterable}
29 請(qǐng)反轉(zhuǎn)字符串 “aStr”?
print("aStr"[::-1])
30 將字符串 “k:1 |k1:2|k2:3|k3:4”,處理成字典
str1 = "k:1|k1:2|k2:3|k3:4"
def str2dict(str1):dict1 = {}for iterms in str1.split('|'):key,value = iterms.split(':')dict1[key] = valuereturn dict1
#字典推導(dǎo)式
d = {k:int(v) for t in str1.split("|") for k, v in (t.split(":"), )}
31 請(qǐng)按alist中元素的age由大到小排序
alist = [{'name':'a','age':20},{'name':'b','age':30},{'name':'c','age':25}]
def sort_by_age(list1):return sorted(alist,key=lambda x:x['age'],reverse=True)
32 下面代碼的輸出結(jié)果將是什么?
list = ['a','b','c','d','e']
print(list[10:])
代碼將輸出[],不會(huì)產(chǎn)生IndexError錯(cuò)誤,就像所期望的那樣,嘗試用超出成員的個(gè)數(shù)的index來(lái)獲取某個(gè)列表的成員。例如,嘗試獲取list[10]和之后的成員,會(huì)導(dǎo)致IndexError。然而,嘗試獲取列表的切片,開(kāi)始的index超過(guò)了成員個(gè)數(shù)不會(huì)產(chǎn)生IndexError,而是僅僅返回一個(gè)空列表。這成為特別讓人惡心的疑難雜癥,因?yàn)檫\(yùn)行的時(shí)候沒(méi)有錯(cuò)誤產(chǎn)生,導(dǎo)致Bug很難被追蹤到。
33 寫(xiě)一個(gè)列表生成式,產(chǎn)生一個(gè)公差為11的等差數(shù)列
print([x*11 for x in range(10)])
34 給定兩個(gè)列表,怎么找出他們相同的元素和不同的元素?
list1 = [1,2,3]
list2 = [3,4,5]
set1 = set(list1)
set2 = set(list2)
print(set1 & set2)
print(set1 ^ set2)
35 請(qǐng)寫(xiě)出一段python代碼實(shí)現(xiàn)刪除list里面的重復(fù)元素?
l1 = ['b','c','d','c','a','a']
l2 = list(set(l1))
print(l2)
用list類(lèi)的sort方法:
l1 = ['b','c','d','c','a','a']
l2 = list(set(l1))
l2.sort(key=l1.index)
print(l2)
也可以這樣寫(xiě):
l1 = ['b','c','d','c','a','a']
l2 = sorted(set(l1),key=l1.index)
print(l2)
也可以用遍歷:
'''
遇到問(wèn)題沒(méi)人解答?小編創(chuàng)建了一個(gè)Python學(xué)習(xí)交流QQ群:857662006 尋找有志同道合的小伙伴,
互幫互助,群里還有不錯(cuò)的視頻學(xué)習(xí)教程和PDF電子書(shū)!
'''
l1 = ['b','c','d','c','a','a']
l2 = []
for i in l1:if not i in l2:l2.append(i)
print(l2)
36 給定兩個(gè)list A,B ,請(qǐng)用找出A,B中相同與不同的元素
A,B 中相同元素:print(set(A)&set(B))
A,B 中不同元素: print(set(A)^set(B))
37 python新式類(lèi)和經(jīng)典類(lèi)的區(qū)別?
a. 在python里凡是繼承了object的類(lèi),都是新式類(lèi)
b. Python3里只有新式類(lèi)
c. Python2里面繼承object的是新式類(lèi),沒(méi)有寫(xiě)父類(lèi)的是經(jīng)典類(lèi)
d. 經(jīng)典類(lèi)目前在Python里基本沒(méi)有應(yīng)用
38 python中內(nèi)置的數(shù)據(jù)結(jié)構(gòu)有幾種?
a. 整型 int、 長(zhǎng)整型 long、浮點(diǎn)型 float、 復(fù)數(shù) complex
b. 字符串 str、 列表 list、 元祖 tuple
c. 字典 dict 、 集合 set
d. Python3 中沒(méi)有 long,只有無(wú)限精度的 int
39 python如何實(shí)現(xiàn)單例模式?請(qǐng)寫(xiě)出兩種實(shí)現(xiàn)方式?
第一種方法:使用裝飾器
'''
遇到問(wèn)題沒(méi)人解答?小編創(chuàng)建了一個(gè)Python學(xué)習(xí)交流QQ群:857662006 尋找有志同道合的小伙伴,
互幫互助,群里還有不錯(cuò)的視頻學(xué)習(xí)教程和PDF電子書(shū)!
'''
def singleton(cls):instances = {}def wrapper(*args, **kwargs):if cls not in instances:instances[cls] = cls(*args, **kwargs)return instances[cls]return wrapper@singleton
class Foo(object):pass
foo1 = Foo()
foo2 = Foo()
print(foo1 is foo2) # True
第二種方法:使用基類(lèi)
New 是真正創(chuàng)建實(shí)例對(duì)象的方法,所以重寫(xiě)基類(lèi)的new 方法,以此保證創(chuàng)建對(duì)象的時(shí)候只生成一個(gè)實(shí)例
class Singleton(object):def __new__(cls, *args, **kwargs):if not hasattr(cls, '_instance'):cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)return cls._instanceclass Foo(Singleton):passfoo1 = Foo()
foo2 = Foo()print(foo1 is foo2) # True
第三種方法:元類(lèi),元類(lèi)是用于創(chuàng)建類(lèi)對(duì)象的類(lèi),類(lèi)對(duì)象創(chuàng)建實(shí)例對(duì)象時(shí)一定要調(diào)用call方法,因此在調(diào)用call時(shí)候保證始終只創(chuàng)建一個(gè)實(shí)例即可,type是python的元類(lèi)
'''
遇到問(wèn)題沒(méi)人解答?小編創(chuàng)建了一個(gè)Python學(xué)習(xí)交流QQ群:857662006 尋找有志同道合的小伙伴,
互幫互助,群里還有不錯(cuò)的視頻學(xué)習(xí)教程和PDF電子書(shū)!
'''
class Singleton(type):def __call__(cls, *args, **kwargs):if not hasattr(cls, '_instance'):cls._instance = super(Singleton, cls).__call__(*args, **kwargs)return cls._instance# Python2
class Foo(object):__metaclass__ = Singleton# Python3
class Foo(metaclass=Singleton):passfoo1 = Foo()
foo2 = Foo()
print(foo1 is foo2) # True
40 反轉(zhuǎn)一個(gè)整數(shù),例如-123 --> -321
class Solution(object):def reverse(self,x):if -10<x<10:return xstr_x = str(x)if str_x[0] !="-":str_x = str_x[::-1]x = int(str_x)else:str_x = str_x[1:][::-1]x = int(str_x)x = -xreturn x if -2147483648<x<2147483647 else 0
if __name__ == '__main__':s = Solution()reverse_int = s.reverse(-120)print(reverse_int)
41 設(shè)計(jì)實(shí)現(xiàn)遍歷目錄與子目錄,抓取.pyc文件?
第一種方法:
import osdef get_files(dir,suffix):res = []for root,dirs,files in os.walk(dir):for filename in files:name,suf = os.path.splitext(filename)if suf == suffix:res.append(os.path.join(root,filename))print(res)get_files("./",'.pyc')
第二種方法:
import osdef pick(obj):if ob.endswith(".pyc"):print(obj)def scan_path(ph):file_list = os.listdir(ph)for obj in file_list:if os.path.isfile(obj):pick(obj)elif os.path.isdir(obj):scan_path(obj)if __name__=='__main__':path = input('輸入目錄')scan_path(path)
第三種方法
'''
遇到問(wèn)題沒(méi)人解答?小編創(chuàng)建了一個(gè)Python學(xué)習(xí)交流QQ群:857662006 尋找有志同道合的小伙伴,
互幫互助,群里還有不錯(cuò)的視頻學(xué)習(xí)教程和PDF電子書(shū)!
'''
from glob import iglobdef func(fp, postfix):for i in iglob(f"{fp}/**/*{postfix}", recursive=True):print(i)if __name__ == "__main__":postfix = ".pyc"func("K:\Python_script", postfix)
42 Python-遍歷列表時(shí)刪除元素的正確做法
遍歷在新在列表操作,刪除時(shí)在原來(lái)的列表操作
a = [1,2,3,4,5,6,7,8]
print(id(a))
print(id(a[:]))
for i in a[:]:if i>5:passelse:a.remove(i)print(a)
print('-----------')
print(id(a))
#filter
a=[1,2,3,4,5,6,7,8]
b = filter(lambda x: x>5,a)
print(list(b))
列表解析
a=[1,2,3,4,5,6,7,8]
b = [i for i in a if i>5]
print(b)
倒序刪除
因?yàn)榱斜砜偸恰蚯耙啤?#xff0c;所以可以倒序遍歷,即使后面的元素被修改了,還沒(méi)有被遍歷的元素和其坐標(biāo)還是保持不變的
a=[1,2,3,4,5,6,7,8]
print(id(a))
for i in range(len(a)-1,-1,-1):if a[i]>5:passelse:a.remove(a[i])
print(id(a))
print('-----------')
print(a)
43 字符串的操作題目
全字母短句 PANGRAM 是包含所有英文字母的句子,比如:A QUICK BROWN FOX JUMPS OVER THE LAZY DOG. 定義并實(shí)現(xiàn)一個(gè)方法 get_missing_letter, 傳入一個(gè)字符串采納數(shù),返回參數(shù)字符串變成一個(gè) PANGRAM 中所缺失的字符。應(yīng)該忽略傳入字符串參數(shù)中的大小寫(xiě),返回應(yīng)該都是小寫(xiě)字符并按字母順序排序(請(qǐng)忽略所有非 ACSII 字符)
下面示例是用來(lái)解釋,雙引號(hào)不需要考慮:
(0)輸入: “A quick brown for jumps over the lazy dog”
返回:""
(1)輸入: “A slow yellow fox crawls under the proactive dog”
返回: “bjkmqz”
(2)輸入: “Lions, and tigers, and bears, oh my!”
返回: “cfjkpquvwxz”
(3)輸入: “”
返回:“abcdefghijklmnopqrstuvwxyz”
'''
遇到問(wèn)題沒(méi)人解答?小編創(chuàng)建了一個(gè)Python學(xué)習(xí)交流QQ群:857662006 尋找有志同道合的小伙伴,
互幫互助,群里還有不錯(cuò)的視頻學(xué)習(xí)教程和PDF電子書(shū)!
'''
def get_missing_letter(a):s1 = set("abcdefghijklmnopqrstuvwxyz")s2 = set(a)ret = "".join(sorted(s1-s2))return retprint(get_missing_letter("python"))
44 可變類(lèi)型和不可變類(lèi)型
1,可變類(lèi)型有l(wèi)ist,dict.不可變類(lèi)型有string,number,tuple.
2,當(dāng)進(jìn)行修改操作時(shí),可變類(lèi)型傳遞的是內(nèi)存中的地址,也就是說(shuō),直接修改內(nèi)存中的值,并沒(méi)有開(kāi)辟新的內(nèi)存。
3,不可變類(lèi)型被改變時(shí),并沒(méi)有改變?cè)瓋?nèi)存地址中的值,而是開(kāi)辟一塊新的內(nèi)存,將原地址中的值復(fù)制過(guò)去,對(duì)這塊新開(kāi)辟的內(nèi)存中的值進(jìn)行操作。
45 is和==有什么區(qū)別?
is:比較的是兩個(gè)對(duì)象的id值是否相等,也就是比較倆對(duì)象是否為同一個(gè)實(shí)例對(duì)象。是否指向同一個(gè)內(nèi)存地址
== :比較的兩個(gè)對(duì)象的內(nèi)容/值是否相等,默認(rèn)會(huì)調(diào)用對(duì)象的eq()方法
46 求出列表所有奇數(shù)并構(gòu)造新列表
a = [1,2,3,4,5,6,7,8,9,10]
res = [ i for i in a if i%2==1]
print(res)
47 用一行python代碼寫(xiě)出1+2+3+10248
from functools import reduce
#1.使用sum內(nèi)置求和函數(shù)
num = sum([1,2,3,10248])
print(num)
#2.reduce 函數(shù)
num1 = reduce(lambda x,y :x+y,[1,2,3,10248])
print(num1)
48 Python中變量的作用域?(變量查找順序)
函數(shù)作用域的LEGB順序
1.什么是LEGB?
L:local 函數(shù)內(nèi)部作用域
E: enclosing 函數(shù)內(nèi)部與內(nèi)嵌函數(shù)之間
G: global 全局作用域
B:build-in 內(nèi)置作用
python在函數(shù)里面的查找分為4種,稱(chēng)之為L(zhǎng)EGB,也正是按照這是順序來(lái)查找的
49 字符串 "123" 轉(zhuǎn)換成 123,不使用內(nèi)置api,例如 int()
方法一:利用 str 函數(shù)
def atoi(s):num = 0for v in s:for j in range(10):if v == str(j):num = num * 10 + jreturn num
方法二:利用 ord 函數(shù)
def atoi(s):num = 0for v in s:num = num * 10 + ord(v) - ord('0')return num
方法三: 利用 eval 函數(shù)
def atoi(s):num = 0for v in s:t = "%s * 1" % vn = eval(t)num = num * 10 + nreturn num
方法四: 結(jié)合方法二,使用 reduce,一行解決
from functools import reduce
def atoi(s):return reduce(lambda num, v: num * 10 + ord(v) - ord('0'), s, 0)
50 Given an array of integers
給定一個(gè)整數(shù)數(shù)組和一個(gè)目標(biāo)值,找出數(shù)組中和為目標(biāo)值的兩個(gè)數(shù)。你可以假設(shè)每個(gè)輸入只對(duì)應(yīng)一種答案,且同樣的元素不能被重復(fù)利用。示例:給定nums = [2,7,11,15],target=9 因?yàn)?nums[0]+nums[1] = 2+7 =9,所以返回[0,1]
'''
遇到問(wèn)題沒(méi)人解答?小編創(chuàng)建了一個(gè)Python學(xué)習(xí)交流QQ群:857662006 尋找有志同道合的小伙伴,
互幫互助,群里還有不錯(cuò)的視頻學(xué)習(xí)教程和PDF電子書(shū)!
'''
class Solution:def twoSum(self,nums,target):""":type nums: List[int]:type target: int:rtype: List[int]"""d = {}size = 0while size < len(nums):if target-nums[size] in d:if d[target-nums[size]] <size:return [d[target-nums[size]],size]else:d[nums[size]] = sizesize = size +1
solution = Solution()
list = [2,7,11,15]
target = 9
nums = solution.twoSum(list,target)
print(nums)
給列表中的字典排序:假設(shè)有如下list對(duì)象,alist=[{“name”:“a”,“age”:20},{“name”:“b”,“age”:30},{“name”:“c”,“age”:25}],將alist中的元素按照age從大到小排序 alist=[{“name”:“a”,“age”:20},{“name”:“b”,“age”:30},{“name”:“c”,“age”:25}]
alist_sort = sorted(alist,key=lambda e: e.__getitem__('age'),reverse=True)
51 python代碼實(shí)現(xiàn)刪除一個(gè)list里面的重復(fù)元素
def distFunc1(a):"""使用集合去重"""a = list(set(a))print(a)def distFunc2(a):"""將一個(gè)列表的數(shù)據(jù)取出放到另一個(gè)列表中,中間作判斷"""list = []for i in a:if i not in list:list.append(i)#如果需要排序的話(huà)用sortlist.sort()print(list)def distFunc3(a):"""使用字典"""b = {}b = b.fromkeys(a)c = list(b.keys())print(c)if __name__ == "__main__":a = [1,2,4,2,4,5,7,10,5,5,7,8,9,0,3]distFunc1(a)distFunc2(a)distFunc3(a)
52 統(tǒng)計(jì)一個(gè)文本中單詞頻次最高的10個(gè)單詞?
import re# 方法一
def test(filepath):distone = {}with open(filepath) as f:for line in f:line = re.sub("\W+", " ", line)lineone = line.split()for keyone in lineone:if not distone.get(keyone):distone[keyone] = 1else:distone[keyone] += 1num_ten = sorted(distone.items(), key=lambda x:x[1], reverse=True)[:10]num_ten =[x[0] for x in num_ten]return num_ten# 方法二
# 使用 built-in 的 Counter 里面的 most_common
import re
from collections import Counterdef test2(filepath):with open(filepath) as f:return list(map(lambda c: c[0], Counter(re.sub("\W+", " ", f.read()).split()).most_common(10)))
53 請(qǐng)寫(xiě)出一個(gè)函數(shù)滿(mǎn)足以下條件
該函數(shù)的輸入是一個(gè)僅包含數(shù)字的list,輸出一個(gè)新的list,其中每一個(gè)元素要滿(mǎn)足以下條件:
1、該元素是偶數(shù)
2、該元素在原list中是在偶數(shù)的位置(index是偶數(shù))
def num_list(num):return [i for i in num if i %2 ==0 and num.index(i)%2==0]num = [0,1,2,3,4,5,6,7,8,9,10]
result = num_list(num)
print(result)
54 使用單一的列表生成式來(lái)產(chǎn)生一個(gè)新的列表
該列表只包含滿(mǎn)足以下條件的值,元素為原始列表中偶數(shù)切片
list_data = [1,2,5,8,10,3,18,6,20]
res = [x for x in list_data[::2] if x %2 ==0]
print(res)
55 用一行代碼生成[1,4,9,16,25,36,49,64,81,100]
[x * x for x in range(1,11)]
56 輸入某年某月某日,判斷這一天是這一年的第幾天?
import datetimey = int(input("請(qǐng)輸入4位數(shù)字的年份:"))
m = int(input("請(qǐng)輸入月份:"))
d = int(input("請(qǐng)輸入是哪一天"))targetDay = datetime.date(y,m,d)
dayCount = targetDay - datetime.date(targetDay.year -1,12,31)
print("%s是 %s年的第%s天。"%(targetDay,y,dayCount.days))
57 兩個(gè)有序列表,l1,l2,對(duì)這兩個(gè)列表進(jìn)行合并不可使用extend
def loop_merge_sort(l1,l2):tmp = []while len(l1)>0 and len(l2)>0:if l1[0] <l2[0]:tmp.append(l1[0])del l1[0]else:tmp.append(l2[0])del l2[0]while len(l1)>0:tmp.append(l1[0])del l1[0]while len(l2)>0:tmp.append(l2[0])del l2[0]return tmp
58 給定一個(gè)任意長(zhǎng)度數(shù)組,實(shí)現(xiàn)一個(gè)函數(shù)
讓所有奇數(shù)都在偶數(shù)前面,而且奇數(shù)升序排列,偶數(shù)降序排序,如字符串’1982376455’,變成’1355798642’
# 方法一
def func1(l):if isinstance(l, str):l = [int(i) for i in l]l.sort(reverse=True)for i in range(len(l)):if l[i] % 2 > 0:l.insert(0, l.pop(i))print(''.join(str(e) for e in l))# 方法二
def func2(l):print("".join(sorted(l, key=lambda x: int(x) % 2 == 0 and 20 - int(x) or int(x))))
59 寫(xiě)一個(gè)函數(shù)找出一個(gè)整數(shù)數(shù)組中,第二大的數(shù)
'''
遇到問(wèn)題沒(méi)人解答?小編創(chuàng)建了一個(gè)Python學(xué)習(xí)交流QQ群:857662006 尋找有志同道合的小伙伴,
互幫互助,群里還有不錯(cuò)的視頻學(xué)習(xí)教程和PDF電子書(shū)!
'''
def find_second_large_num(num_list):"""找出數(shù)組第2大的數(shù)字"""# 方法一# 直接排序,輸出倒數(shù)第二個(gè)數(shù)即可tmp_list = sorted(num_list)print("方法一\nSecond_large_num is :", tmp_list[-2])# 方法二# 設(shè)置兩個(gè)標(biāo)志位一個(gè)存儲(chǔ)最大數(shù)一個(gè)存儲(chǔ)次大數(shù)# two 存儲(chǔ)次大值,one 存儲(chǔ)最大值,遍歷一次數(shù)組即可,先判斷是否大于 one,若大于將 one 的值給 two,將 num_list[i] 的值給 one,否則比較是否大于two,若大于直接將 num_list[i] 的值給two,否則passone = num_list[0]two = num_list[0]for i in range(1, len(num_list)):if num_list[i] > one:two = oneone = num_list[i]elif num_list[i] > two:two = num_list[i]print("方法二\nSecond_large_num is :", two)# 方法三# 用 reduce 與邏輯符號(hào) (and, or)# 基本思路與方法二一樣,但是不需要用 if 進(jìn)行判斷。from functools import reducenum = reduce(lambda ot, x: ot[1] < x and (ot[1], x) or ot[0] < x and (x, ot[1]) or ot, num_list, (0, 0))[0]print("方法三\nSecond_large_num is :", num)if __name__ == '__main___':num_list = [34, 11, 23, 56, 78, 0, 9, 12, 3, 7, 5]find_second_large_num(num_list)
60 閱讀一下代碼他們的輸出結(jié)果是什么?
def multi():return [lambda x : i*x for i in range(4)]
print([m(3) for m in multi()])
正確答案是[9,9,9,9],而不是[0,3,6,9]產(chǎn)生的原因是Python的閉包的后期綁定導(dǎo)致的,這意味著在閉包中的變量是在內(nèi)部函數(shù)被調(diào)用的時(shí)候被查找的,因?yàn)?#xff0c;最后函數(shù)被調(diào)用的時(shí)候,for循環(huán)已經(jīng)完成, i 的值最后是3,因此每一個(gè)返回值的i都是3,所以最后的結(jié)果是[9,9,9,9]
61 統(tǒng)計(jì)一段字符串中字符出現(xiàn)的次數(shù)
# 方法一
def count_str(str_data):"""定義一個(gè)字符出現(xiàn)次數(shù)的函數(shù)"""dict_str = {} for i in str_data:dict_str[i] = dict_str.get(i, 0) + 1return dict_str
dict_str = count_str("AAABBCCAC")
str_count_data = ""
for k, v in dict_str.items():str_count_data += k + str(v)
print(str_count_data)# 方法二
from collections import Counterprint("".join(map(lambda x: x[0] + str(x[1]), Counter("AAABBCCAC").most_common())))
62 Python中類(lèi)方法、類(lèi)實(shí)例方法、靜態(tài)方法有何區(qū)別?
類(lèi)方法: 是類(lèi)對(duì)象的方法,在定義時(shí)需要在上方使用 @classmethod 進(jìn)行裝飾,形參為cls,表示類(lèi)對(duì)象,類(lèi)對(duì)象和實(shí)例對(duì)象都可調(diào)用
類(lèi)實(shí)例方法: 是類(lèi)實(shí)例化對(duì)象的方法,只有實(shí)例對(duì)象可以調(diào)用,形參為self,指代對(duì)象本身;
靜態(tài)方法: 是一個(gè)任意函數(shù),在其上方使用 @staticmethod 進(jìn)行裝飾,可以用對(duì)象直接調(diào)用,靜態(tài)方法實(shí)際上跟該類(lèi)沒(méi)有太大關(guān)系
63 遍歷一個(gè)object的所有屬性,并print每一個(gè)屬性名?
class Car:def __init__(self,name,loss): # loss [價(jià)格,油耗,公里數(shù)]self.name = nameself.loss = lossdef getName(self):return self.namedef getPrice(self):# 獲取汽車(chē)價(jià)格return self.loss[0]def getLoss(self):# 獲取汽車(chē)損耗值return self.loss[1] * self.loss[2]Bmw = Car("寶馬",[60,9,500]) # 實(shí)例化一個(gè)寶馬車(chē)對(duì)象
print(getattr(Bmw,"name")) # 使用getattr()傳入對(duì)象名字,屬性值。
print(dir(Bmw)) # 獲Bmw所有的屬性和方法
64 寫(xiě)一個(gè)類(lèi),并讓它盡可能多的支持操作符?
class Array:__list = []def __init__(self):print "constructor"def __del__(self):print "destruct"def __str__(self):return "this self-defined array class"def __getitem__(self,key):return self.__list[key]def __len__(self):return len(self.__list)def Add(self,value):self.__list.append(value)def Remove(self,index):del self.__list[index]def DisplayItems(self):print "show all items---"for item in self.__list:print item
65 關(guān)于Python內(nèi)存管理,下列說(shuō)法錯(cuò)誤的是 B
A,變量不必事先聲明 B,變量無(wú)須先創(chuàng)建和賦值而直接使用
C,變量無(wú)須指定類(lèi)型 D,可以使用del釋放資源
66 Python的內(nèi)存管理機(jī)制及調(diào)優(yōu)手段?
內(nèi)存管理機(jī)制: 引用計(jì)數(shù)、垃圾回收、內(nèi)存池
引用計(jì)數(shù):引用計(jì)數(shù)是一種非常高效的內(nèi)存管理手段,當(dāng)一個(gè)Python對(duì)象被引用時(shí)其引用計(jì)數(shù)增加1,
當(dāng)其不再被一個(gè)變量引用時(shí)則計(jì)數(shù)減1,當(dāng)引用計(jì)數(shù)等于0時(shí)對(duì)象被刪除。弱引用不會(huì)增加引用計(jì)數(shù)
垃圾回收:
1.引用計(jì)數(shù)
引用計(jì)數(shù)也是一種垃圾收集機(jī)制,而且也是一種最直觀(guān)、最簡(jiǎn)單的垃圾收集技術(shù)。當(dāng)Python的某個(gè)對(duì)象的引用計(jì)數(shù)降為0時(shí),說(shuō)明沒(méi)有任何引用指向該對(duì)象,該對(duì)象就成為要被回收的垃圾了。比如某個(gè)新建對(duì)象,它被分配給某個(gè)引用,對(duì)象的引用計(jì)數(shù)變?yōu)?,如果引用被刪除,對(duì)象的引用計(jì)數(shù)為0,那么該對(duì)象就可以被垃圾回收。不過(guò)如果出現(xiàn)循環(huán)引用的話(huà),引用計(jì)數(shù)機(jī)制就不再起有效的作用了。
2.標(biāo)記清除
調(diào)優(yōu)手段
1.手動(dòng)垃圾回收
2.調(diào)高垃圾回收閾值
3.避免循環(huán)引用
67 內(nèi)存泄露是什么?如何避免?
內(nèi)存泄漏指由于疏忽或錯(cuò)誤造成程序未能釋放已經(jīng)不再使用的內(nèi)存。內(nèi)存泄漏并非指內(nèi)存在物理上的消失,而是應(yīng)用程序分配某段內(nèi)存后,由于設(shè)計(jì)錯(cuò)誤,導(dǎo)致在釋放該段內(nèi)存之前就失去了對(duì)該段內(nèi)存的控制,從而造成了內(nèi)存的浪費(fèi)。
有__del__()函數(shù)的對(duì)象間的循環(huán)引用是導(dǎo)致內(nèi)存泄露的主兇。不使用一個(gè)對(duì)象時(shí)使用: del object 來(lái)刪除一個(gè)對(duì)象的引用計(jì)數(shù)就可以有效防止內(nèi)存泄露問(wèn)題。
通過(guò)Python擴(kuò)展模塊gc 來(lái)查看不能回收的對(duì)象的詳細(xì)信息。
可以通過(guò) sys.getrefcount(obj) 來(lái)獲取對(duì)象的引用計(jì)數(shù),并根據(jù)返回值是否為0來(lái)判斷是否內(nèi)存泄露
68 python常見(jiàn)的列表推導(dǎo)式?
[表達(dá)式 for 變量 in 列表] 或者 [表達(dá)式 for 變量 in 列表 if 條件]
69 簡(jiǎn)述read、readline、readlines的區(qū)別?
read 讀取整個(gè)文件
readline 讀取下一行
readlines 讀取整個(gè)文件到一個(gè)迭代器以供我們遍歷
70 什么是Hash(散列函數(shù))?
散列函數(shù)(英語(yǔ):Hash function)又稱(chēng)散列算法、哈希函數(shù),是一種從任何一種數(shù)據(jù)中創(chuàng)建小的數(shù)字“指紋”的方法。散列函數(shù)把消息或數(shù)據(jù)壓縮成摘要,使得數(shù)據(jù)量變小,將數(shù)據(jù)的格式固定下來(lái)。該函數(shù)將數(shù)據(jù)打亂混合,重新創(chuàng)建一個(gè)叫做散列值(hash values,hash codes,hash sums,或hashes)的指紋。散列值通常用一個(gè)短的隨機(jī)字母和數(shù)字組成的字符串來(lái)代表
71 python函數(shù)重載機(jī)制?
函數(shù)重載主要是為了解決兩個(gè)問(wèn)題。
1。可變參數(shù)類(lèi)型。
2。可變參數(shù)個(gè)數(shù)。
另外,一個(gè)基本的設(shè)計(jì)原則是,僅僅當(dāng)兩個(gè)函數(shù)除了參數(shù)類(lèi)型和參數(shù)個(gè)數(shù)不同以外,其功能是完全相同的,此時(shí)才使用函數(shù)重載,如果兩個(gè)函數(shù)的功能其實(shí)不同,那么不應(yīng)當(dāng)使用重載,而應(yīng)當(dāng)使用一個(gè)名字不同的函數(shù)。
好吧,那么對(duì)于情況 1 ,函數(shù)功能相同,但是參數(shù)類(lèi)型不同,python 如何處理?答案是根本不需要處理,因?yàn)?python 可以接受任何類(lèi)型的參數(shù),如果函數(shù)的功能相同,那么不同的參數(shù)類(lèi)型在 python 中很可能是相同的代碼,沒(méi)有必要做成兩個(gè)不同函數(shù)。
那么對(duì)于情況 2 ,函數(shù)功能相同,但參數(shù)個(gè)數(shù)不同,python 如何處理?大家知道,答案就是缺省參數(shù)。對(duì)那些缺少的參數(shù)設(shè)定為缺省參數(shù)即可解決問(wèn)題。因?yàn)槟慵僭O(shè)函數(shù)功能相同,那么那些缺少的參數(shù)終歸是需要用的。
好了,鑒于情況 1 跟 情況 2 都有了解決方案,python 自然就不需要函數(shù)重載了。
72 手寫(xiě)一個(gè)判斷時(shí)間的裝飾器
'''
遇到問(wèn)題沒(méi)人解答?小編創(chuàng)建了一個(gè)Python學(xué)習(xí)交流QQ群:857662006 尋找有志同道合的小伙伴,
互幫互助,群里還有不錯(cuò)的視頻學(xué)習(xí)教程和PDF電子書(shū)!
'''
import datetimeclass TimeException(Exception):def __init__(self, exception_info):super().__init__()self.info = exception_infodef __str__(self):return self.infodef timecheck(func):def wrapper(*args, **kwargs):if datetime.datetime.now().year == 2019:func(*args, **kwargs)else:raise TimeException("函數(shù)已過(guò)時(shí)")return wrapper@timecheck
def test(name):print("Hello {}, 2019 Happy".format(name))if __name__ == "__main__":test("backbp")
73 使用Python內(nèi)置的filter()方法來(lái)過(guò)濾?
list(filter(lambda x: x % 2 == 0, range(10)))
74 編寫(xiě)函數(shù)的4個(gè)原則
1.函數(shù)設(shè)計(jì)要盡量短小
2.函數(shù)聲明要做到合理、簡(jiǎn)單、易于使用
3.函數(shù)參數(shù)設(shè)計(jì)應(yīng)該考慮向下兼容
4.一個(gè)函數(shù)只做一件事情,盡量保證函數(shù)語(yǔ)句粒度的一致性
75 函數(shù)調(diào)用參數(shù)的傳遞方式是值傳遞還是引用傳遞?
Python的參數(shù)傳遞有:位置參數(shù)、默認(rèn)參數(shù)、可變參數(shù)、關(guān)鍵字參數(shù)。
函數(shù)的傳值到底是值傳遞還是引用傳遞、要分情況:
不可變參數(shù)用值傳遞:像整數(shù)和字符串這樣的不可變對(duì)象,是通過(guò)拷貝進(jìn)行傳遞的,因?yàn)槟銦o(wú)論如何都不可能在原處改變不可變對(duì)象。
可變參數(shù)是引用傳遞:比如像列表,字典這樣的對(duì)象是通過(guò)引用傳遞、和C語(yǔ)言里面的用指針傳遞數(shù)組很相似,可變對(duì)象能在函數(shù)內(nèi)部改變。
76 如何在function里面設(shè)置一個(gè)全局變量
globals() # 返回包含當(dāng)前作用余全局變量的字典。
global 變量 設(shè)置使用全局變量
77 對(duì)缺省參數(shù)的理解 ?
缺省參數(shù)指在調(diào)用函數(shù)的時(shí)候沒(méi)有傳入?yún)?shù)的情況下,調(diào)用默認(rèn)的參數(shù),在調(diào)用函數(shù)的同時(shí)賦值時(shí),所傳入的參數(shù)會(huì)替代默認(rèn)參數(shù)。
*args是不定長(zhǎng)參數(shù),它可以表示輸入?yún)?shù)是不確定的,可以是任意多個(gè)。
**kwargs是關(guān)鍵字參數(shù),賦值的時(shí)候是以鍵值對(duì)的方式,參數(shù)可以是任意多對(duì)在定義函數(shù)的時(shí)候
不確定會(huì)有多少參數(shù)會(huì)傳入時(shí),就可以使用兩個(gè)參數(shù)
78 帶參數(shù)的裝飾器?
帶定長(zhǎng)參數(shù)的裝飾器
def new_func(func):def wrappedfun(username, passwd):if username == 'root' and passwd == '123456789':print('通過(guò)認(rèn)證')print('開(kāi)始執(zhí)行附加功能')return func()else:print('用戶(hù)名或密碼錯(cuò)誤')returnreturn wrappedfun@new_func
def origin():print('開(kāi)始執(zhí)行函數(shù)')
origin('root','123456789')
帶不定長(zhǎng)參數(shù)的裝飾器
def new_func(func):def wrappedfun(*parts):if parts:counts = len(parts)print('本系統(tǒng)包含 ', end='')for part in parts:print(part, ' ',end='')print('等', counts, '部分')return func()else:print('用戶(hù)名或密碼錯(cuò)誤')return func()return wrappedfun
79 為什么函數(shù)名字可以當(dāng)做參數(shù)用?
Python中一切皆對(duì)象,函數(shù)名是函數(shù)在內(nèi)存中的空間,也是一個(gè)對(duì)象
80 Python中pass語(yǔ)句的作用是什么?
在編寫(xiě)代碼時(shí)只寫(xiě)框架思路,具體實(shí)現(xiàn)還未編寫(xiě)就可以用pass進(jìn)行占位,是程序不報(bào)錯(cuò),不會(huì)進(jìn)行任何操作。
81 有這樣一段代碼,print c會(huì)輸出什么,為什么?
a = 10
b = 20
c = [a]
a = 15
答:10對(duì)于字符串,數(shù)字,傳遞是相應(yīng)的值
82 交換兩個(gè)變量的值?
a, b = b, a
83 map函數(shù)和reduce函數(shù)?
map(lambda x: x * x, [1, 2, 3, 4]) # 使用 lambda
# [1, 4, 9, 16]
reduce(lambda x, y: x * y, [1, 2, 3, 4]) # 相當(dāng)于 ((1 * 2) * 3) * 4
# 24
84 回調(diào)函數(shù),如何通信的?
回調(diào)函數(shù)是把函數(shù)的指針(地址)作為參數(shù)傳遞給另一個(gè)函數(shù),將整個(gè)函數(shù)當(dāng)作一個(gè)對(duì)象,賦值給調(diào)用的函數(shù)。
85 Python主要的內(nèi)置數(shù)據(jù)類(lèi)型都有哪些?print dir( ‘a(chǎn) ’) 的輸出?
內(nèi)建類(lèi)型:布爾類(lèi)型,數(shù)字,字符串,列表,元組,字典,集合
輸出字符串’a’的內(nèi)建方法
86 map(lambda x:xx,[y for y in range(3)])的輸出?
[0, 1, 4]
87 hasattr() getattr() setattr() 函數(shù)使用詳解?
hasattr(object,name)函數(shù):
判斷一個(gè)對(duì)象里面是否有name屬性或者name方法,返回bool值,有name屬性(方法)返回True,否則返回False。
'''
遇到問(wèn)題沒(méi)人解答?小編創(chuàng)建了一個(gè)Python學(xué)習(xí)交流QQ群:857662006 尋找有志同道合的小伙伴,
互幫互助,群里還有不錯(cuò)的視頻學(xué)習(xí)教程和PDF電子書(shū)!
'''
class function_demo(object):name = 'demo'def run(self):return "hello function"
functiondemo = function_demo()
res = hasattr(functiondemo, "name") # 判斷對(duì)象是否有name屬性,True
res = hasattr(functiondemo, "run") # 判斷對(duì)象是否有run方法,True
res = hasattr(functiondemo, "age") # 判斷對(duì)象是否有age屬性,False
print(res)
getattr(object, name[,default])函數(shù):
獲取對(duì)象object的屬性或者方法,如果存在則打印出來(lái),如果不存在,打印默認(rèn)值,默認(rèn)值可選。注意:如果返回的是對(duì)象的方法,則打印結(jié)果是:方法的內(nèi)存地址,如果需要運(yùn)行這個(gè)方法,可以在后面添加括號(hào)().
functiondemo = function_demo()
getattr(functiondemo, "name")# 獲取name屬性,存在就打印出來(lái) --- demo
getattr(functiondemo, "run") # 獲取run 方法,存在打印出方法的內(nèi)存地址
getattr(functiondemo, "age") # 獲取不存在的屬性,報(bào)錯(cuò)
getattr(functiondemo, "age", 18)# 獲取不存在的屬性,返回一個(gè)默認(rèn)值
setattr(object, name, values)函數(shù):
給對(duì)象的屬性賦值,若屬性不存在,先創(chuàng)建再賦值
class function_demo(object):name = "demo"def run(self):return "hello function"
functiondemo = function_demo()
res = hasattr(functiondemo, "age") # 判斷age屬性是否存在,False
print(res)
setattr(functiondemo, "age", 18) # 對(duì)age屬性進(jìn)行賦值,無(wú)返回值
res1 = hasattr(functiondemo, "age") # 再次判斷屬性是否存在,True
綜合使用
class function_demo(object):name = "demo"def run(self):return "hello function"
functiondemo = function_demo()
res = hasattr(functiondemo, "addr") # 先判斷是否存在
if res:addr = getattr(functiondemo, "addr")print(addr)
else:addr = getattr(functiondemo, "addr", setattr(functiondemo, "addr", "北京首都"))print(addr)
88 一句話(huà)解決階乘函數(shù)?
reduce(lambda x,y : x*y,range(1,n+1))
89 對(duì)設(shè)計(jì)模式的理解,簡(jiǎn)述你了解的設(shè)計(jì)模式?
設(shè)計(jì)模式是經(jīng)過(guò)總結(jié),優(yōu)化的,對(duì)我們經(jīng)常會(huì)碰到的一些編程問(wèn)題的可重用解決方案。一個(gè)設(shè)計(jì)模式并不像一個(gè)類(lèi)或一個(gè)庫(kù)那樣能夠直接作用于我們的代碼,反之,設(shè)計(jì)模式更為高級(jí),它是一種必須在特定情形下實(shí)現(xiàn)的一種方法模板。
常見(jiàn)的是工廠(chǎng)模式和單例模式
90 請(qǐng)手寫(xiě)一個(gè)單例
#python2
class A(object):__instance = Nonedef __new__(cls,*args,**kwargs):if cls.__instance is None:cls.__instance = objecet.__new__(cls)return cls.__instanceelse:return cls.__instance
91 單例模式的應(yīng)用場(chǎng)景有那些?
單例模式應(yīng)用的場(chǎng)景一般發(fā)現(xiàn)在以下條件下:
資源共享的情況下,避免由于資源操作時(shí)導(dǎo)致的性能或損耗等,如日志文件,應(yīng)用配置。
控制資源的情況下,方便資源之間的互相通信。如線(xiàn)程池等,1,網(wǎng)站的計(jì)數(shù)器 2,應(yīng)用配置 3.多線(xiàn)程池 4數(shù)據(jù)庫(kù)配置 數(shù)據(jù)庫(kù)連接池 5.應(yīng)用程序的日志應(yīng)用…
92 用一行代碼生成[1,4,9,16,25,36,49,64,81,100]
print([x*x for x in range(1, 11)])
93 對(duì)裝飾器的理解,并寫(xiě)出一個(gè)計(jì)時(shí)器記錄方法執(zhí)行性能的裝飾器?
裝飾器本質(zhì)上是一個(gè)callable object ,它可以讓其他函數(shù)在不需要做任何代碼變動(dòng)的前提下增加額外功能,裝飾器的返回值也是一個(gè)函數(shù)對(duì)象。
'''
遇到問(wèn)題沒(méi)人解答?小編創(chuàng)建了一個(gè)Python學(xué)習(xí)交流QQ群:857662006 尋找有志同道合的小伙伴,
互幫互助,群里還有不錯(cuò)的視頻學(xué)習(xí)教程和PDF電子書(shū)!
'''
import time
from functools import wrapsdef timeit(func):@wraps(func)def wrapper(*args, **kwargs):start = time.clock()ret = func(*args, **kwargs)end = time.clock()print('used:',end-start)return retreturn wrapper
@timeit
def foo():print('in foo()'foo())
94 解釋以下什么是閉包?
在函數(shù)內(nèi)部再定義一個(gè)函數(shù),并且這個(gè)函數(shù)用到了外邊函數(shù)的變量,那么將這個(gè)函數(shù)以及用到的一些變量稱(chēng)之為閉包。
95 函數(shù)裝飾器有什么作用?
裝飾器本質(zhì)上是一個(gè)callable object,它可以在讓其他函數(shù)在不需要做任何代碼的變動(dòng)的前提下增加額外的功能。裝飾器的返回值也是一個(gè)函數(shù)的對(duì)象,它經(jīng)常用于有切面需求的場(chǎng)景。比如:插入日志,性能測(cè)試,事務(wù)處理,緩存。權(quán)限的校驗(yàn)等場(chǎng)景,有了裝飾器就可以抽離出大量的與函數(shù)功能本身無(wú)關(guān)的雷同代碼并發(fā)并繼續(xù)使用。
詳細(xì)參考:https://manjusaka.itscoder.com/2018/02/23/something-about-decorator/
96 生成器,迭代器的區(qū)別?
迭代器是遵循迭代協(xié)議的對(duì)象。用戶(hù)可以使用 iter() 以從任何序列得到迭代器(如 list, tuple, dictionary, set 等)。另一個(gè)方法則是創(chuàng)建一個(gè)另一種形式的迭代器 —— generator 。要獲取下一個(gè)元素,則使用成員函數(shù) next()(Python 2)或函數(shù) next() function (Python 3) 。當(dāng)沒(méi)有元素時(shí),則引發(fā) StopIteration 此例外。若要實(shí)現(xiàn)自己的迭代器,則只要實(shí)現(xiàn) next()(Python 2)或 __next__()( Python 3)
生成器(Generator),只是在需要返回?cái)?shù)據(jù)的時(shí)候使用yield語(yǔ)句。每次next()被調(diào)用時(shí),生成器會(huì)返回它脫離的位置(它記憶語(yǔ)句最后一次執(zhí)行的位置和所有的數(shù)據(jù)值)
區(qū)別:生成器能做到迭代器能做的所有事,而且因?yàn)樽詣?dòng)創(chuàng)建iter()和next()方法,生成器顯得特別簡(jiǎn)潔,而且生成器也是高效的,使用生成器表達(dá)式取代列表解析可以同時(shí)節(jié)省內(nèi)存。除了創(chuàng)建和保存程序狀態(tài)的自動(dòng)方法,當(dāng)發(fā)生器終結(jié)時(shí),還會(huì)自動(dòng)拋出StopIteration異常。
97 X是什么類(lèi)型?
X= (i for i in range(10))
X是 generator類(lèi)型
98 請(qǐng)用一行代碼 實(shí)現(xiàn)將1-N 的整數(shù)列表以3為單位分組
N =100
print ([[x for x in range(1,100)] [i:i+3] for i in range(0,100,3)])
99 Python中yield的用法?
yield就是保存當(dāng)前程序執(zhí)行狀態(tài)。你用for循環(huán)的時(shí)候,每次取一個(gè)元素的時(shí)候就會(huì)計(jì)算一次。用yield的函數(shù)叫g(shù)enerator,和iterator一樣,它的好處是不用一次計(jì)算所有元素,而是用一次算一次,可以節(jié)省很多空間,generator每次計(jì)算需要上一次計(jì)算結(jié)果,所以用yield,否則一return,上次計(jì)算結(jié)果就沒(méi)了
總結(jié)
以上是生活随笔為你收集整理的2019 Python100道 面试 题,你会几道?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 小米回应有品特殊激励需放弃年终奖……外媒
- 下一篇: appemit支持谷歌chrome ed