日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

bd3.2 Python高级

發布時間:2025/5/22 python 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 bd3.2 Python高级 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

四.設計模式

1. 單例
1.1 請手寫一個單例

class SingleMode(object):_instance = Nonedef __new__(cls, *args, **kwargs):if cls._instance is None:cls._instance = object.__new__(cls)return cls._instanceelse:return cls._instance

1.2 單例模式的應用場景有哪些?

單例模式應用的場景一般發現在以下條件下: (1) 資源共享的情況下,避免由于資源操作時導致的性能或損耗等。如日志文件,應用配置。 (2) 控制資源的情況下,方便資源之間的互相通信。如線程池等。
    1.網站的計數器 2.應用配置 3.多線程池 4. 數據庫配置,數據庫連接池 5.應用程序的日志應用....

?

2.工廠函數

3.? 裝飾器

1? 對裝飾器的理解 ,并寫出一個計時器記錄方法執行性能的裝飾器?

裝飾器本質上是一個 Python 函數,它可以讓其他函數在不需要做任何代碼變動的前提下增加額外功能,裝飾器的返回值也是一個函數對象。

import time def timeit(func):def wrapper():start = time.clock()func()end = time.clock()print("use time:",end-start)return wrapper()@timeit def test():for i in range(100):print(i)

?

3.2 解釋一下什么是閉包? 在函數內部再定義一個函數,并且這個函數用到了外邊函數的變量,那么將這個函數以及用到的一些變量稱之為閉包。3.3 函數裝飾器有什么作用? 裝飾器本質上是一個Python 函數,它可以在讓其他函數在不需要做任何代碼的變動的前提下增加額外的功能。
裝飾器的返回值也是一個函數的對象,它經常用于有切面需求的場景。
比如:
  插入日志、性能測試、事務處理、緩存、權限的校驗等場景
有了裝飾器就可以抽離出大量的與函數功能本身無關的雷同代碼并發并繼續使用。

4.? 生成器

  迭代器是一個更抽象的概念,任何對象,如果它的類有 next 方法和 iter 方法返回自己本身,對于 string、list、dict、tuple 等這類容器對象,使用 for 循環遍歷是很方便的。在后臺 for 語句對容器對象調用 iter()函數,iter() 是 python 的內置函數。
  iter()會返回一個定義了 next()方法的迭代器對象,它在容器中逐個訪問容器內元素,next()也是 python 的內置函數。在沒有后續元素時,next()會拋出一個 StopIteration 異常。
生成器(Generator)是創建迭代器的簡單而強大的工具。它們寫起來就像是正規的函數,只是在需要返回數據的時候使用
yield 語句。每次 next()被調用時,生成器會返回它脫離的位置(它記憶語句最后一次執行的位置 和所有的數據值)
區別:
  生成器能做到迭代器能做的所有事,而且因為自動創建了 iter()和 next()方法,生成器顯得特別簡潔,而且生成器也是高效的,使用生成器表達式取代列表解析可以同時節省內存。除了創建和保存程序狀態的自動方法,當 發生器終結時,還會自動拋出 StopIteration 異常。

?

4.2 X 是什么類型?1. X = (for i in ramg(10)) 答:X 是 generator 類型。
4.3 請嘗試用“一行代碼”實現將 1-N的整數列表以 3 為單位分組,比如 1-100 分組后為?

In [30]: print([[x for x in range(1,100)][i:i+3] for i in range(0,100,3)])
[[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12], [13, 14, 15], [16, 17, 18], [19, 20, 21], [22, 23, 24], [25, 26, 27], [28, 29, 30], [31, 32, 33], [34, 35, 36], [37, 38, 39], [40, 41, 42], [43, 44, 45], [46, 47, 48], [49, 50, 51], [52, 53, 54], [55, 56, 57], [58, 59, 60], [61, 62, 63], [64, 65, 66], [67, 68, 69], [70, 71, 72], [73, 74, 75], [76, 77, 78], [79, 80, 81], [82, 83, 84], [85, 86, 87], [88, 89, 90], [91, 92, 93], [94, 95, 96], [97, 98, 99], []]?

?

4.4 Python 中 yield 的用法?

yield
就是保存當前程序執行狀態。你用 for 循環的時候,每次取一個元素的時候就會計算一次。用 yield 的函數 叫 generator,和 iterator 一樣,它的好處是不用一次計算所有元素,而是用一次算一次,可以節省很多空間。generator 每次計算需要上一次計算結果,所以用 yield,否則一 return,上次計算結果就沒了 >>> def createGenerator(): mylist = range(3) for i in mylist: ... yield i*i 5. ... >>> mygenerator = createGenerator() # create a generator >>> print(mygenerator) # mygenerator is an object! <generator object createGenerator at 0xb7555c34> >>> for i in mygenerator: ... print(i) 0 1 4

?

?

五.面向對象

1.1 Python 中的可變對象和不可變對象? 不可變對象,該對象所指向的內存中的值不能被改變。當改變某個變量時候,由于其所指的值不能被改變,相當于把原來的值復制一份后再改變,這會開辟一個新的地址,變量再指向這個新的地址。 可變對象,該對象所指向的內存中的值可以被改變。變量(準確的說是引用)改變后,實際上是其所指的值直接發生改變,并沒有發生復制行為,也沒有開辟新的出地址,通俗點說就是原地改變。 Python 中,數值類型(int 和float)、字符串str、元組tuple 都是不可變類型。而列表 list、字典 dict、集合set 是可變類型。1.2 Python 中 is 和==的區別? is 判斷的是a 對象是否就是b 對象,是通過 id 來判斷的。 ==判斷的是 a 對象的值是否和 b 對象的值相等,是通過 value 來判斷的。

?

1.3 Python 的魔法方法 魔法方法就是可以給你的類增加魔力的特殊方法,如果你的對象實現 (重載)了這些方法中的某一個,那么這個方法就會在特殊的情況下被 Python 所調用,你可以定義自己想要的行為,而這一切都是自動發生的。
它們經常是兩個下劃線包圍來命名的(比如__init__ ,__lt__),Python 的魔法方法是非常強大的,所以了解其使用方法也變得尤為重要! __init__ 構造器,當一個實例被創建的時候初始化的方法。但是它并不是實例化調用的第一個方法。 __new__ 才是實例化對象調用的第一個方法,它只取下cls參數,并把其他參數傳給__init__ 。 __new__很少使用,但是也有它適合的場景,尤其是當類繼承自一個像元組或者字符串這樣不經常改變的類型的時候。__call__ 允許一個類的實例像函數一樣被調用。__getitem__ 定義獲取容器中指定元素的行為,相當于 self[key] 。__getattr__ 定義當用戶試圖訪問一個不存在屬性的時候的行為 。__setattr__ 定義當一個屬性被設置的時候的行為 。__getattribute__ 定義當一個屬性被訪問的時候的行為 。

?

1.4 面向對象中怎么實現只讀屬性?
將對象私有化,通過共有方法提供一個讀取數據的接口

class Person(object):def __init__(self):self.__age = 10# def age(self):# return self.__age @property # 以屬性訪問的方式來訪問私有屬性def age(self):return self.__agep1 = Person() print(p1.age) ?

?

2.5 談談你對面向對象的理解? 面向對象是相對于面向過程而言的。面向過程語言是一種基于功能分析的、以算法為中心的程序設計方法;而面向對象是一種基于結構分析的、以數據為中心的程序設計思想。在面向對象語言中有一個有很重要東西,叫做類。 面向對象有三大特性:封裝、繼承、多態。

六.正則表達式

1. Python 里 match 與 search 的區別? match()函數只檢測 RE 是不是在 string 的開始位置匹配, search()會掃描整個 string 查找匹配; 也就是說 match()只有在0位置匹配成功的話才有返回, 如果不是開始位置匹配成功的話,match()就返回 none。

2. Python 字符串查找和替換?

re.findall(r’目的字符串’,’原有字符串’) #查詢 re.findall(r'cast''itcast.cn')[0] re.sub(r‘要替換原字符’,’要替換新字符’,’原始字符串’) re.sub(r'cast''heima''itcast.cn')

In [1]: import reIn [2]: re.findall(r'cast','itcast.cn') Out[2]: ['cast']In [3]: re.findall(r'cast','itcast.cn')[0] Out[3]: 'cast'In [4]: re.sub(r'cast','heima','itcast.cn') Out[4]: 'itheima.cn'

?

?

3. 用 Python 匹配 HTML tag 的時候,<.*> 和 <.*?> 有什么區別?
<.*>是貪婪匹配,會從第一個“<”開始匹配,直到最后一個“>”中間所有的字符都會匹配到,中間可能會包含“<>”。 <.*?>是非貪婪匹配,從第一個“<”開始往后,遇到第一個“>”結束匹配,這中間的字符串都會匹配到,但是不會有“<>”。

?

請寫出下列正則關鍵字的含義?

?

語法

說明

表達式

實例

完整匹配的

字符串

字符

一般字符

匹配自身

abc

abc

?

.

匹配任意除換行符"\n"外的字符。在 DOTALL 模式中也能匹配換行

符。

?

a.c

?

abc

?

\

轉義字符,使后一個字符改變原來的意思。

如果字符串中有字符*需要匹配,可

以使用\*或者字符集[*]

?

a\.c a\\c

?

a. c a\c

?

?

?

[...]

字符集(字符類)。對應的位置可以是字符集中任意字符。字符集中的字符可以逐個列出,也可以給出范圍, 如[abc]或[a-c]。第一個字符如果是^ 則表示取反,如[^abc]表示不是 abc 的其他字符。

所有的特殊字符在字符集中都失去其原有的特殊含義。在字符集中如果要使用]、-或^,可以在前面加上反斜杠,或把]、-放在第一個字符,把^

放在非第—個字符。

?

?

?

a[bcd]e

?

?

?

abe ace ade

預定義字符集(可以寫在字符集[…]中)

\d

數字:[0-9]

a\dc

a1c

\D

非數字:[^\d]

a\Dc

abc

\s

空白字符:[<空格>\ t\r\n\f\v]

a\sc

ac

\S

非空白字符:[^\s]

a\Sc

abc

\w

單詞字符:[A-Za-z0-9_]

a\wc

abc

\W

非單詞字符:[^\W]

a\Wc

ac

數量詞(用在字符或(…)之后)

*

匹配前一個字符 0 或無限次。

abc*

ab

abccc

+

匹配前一個字符 1 次或無限次

abc+

abc

abccc

?

匹配前一個字符 0 次或 1 次。

abc?

Ab

abc

{m}

匹配前一個字符 m 次

ab{2}c

abbc

?

七.系統編程

1. 進程總結 進程:程序運行在操作系統上的一個實例,就稱之為進程。進程需要相應的系統資源:內存、時間片、pid。
創建進程:
1.首先要導入 multiprocessing 中的 Process; 2.創建一個 Process 對象; 3.創建 Process 對象時,可以傳遞參數; 1.p = Process(target=XXX, args=(元組,) , kwargs={key:value}) 2.target = XXX 指定的任務函數,不用加() 3.args=(元組,) , kwargs={key:value} 給任務函數傳遞的參數

?

4.使用 start()啟動進程; 5.結束進程。


?

Process 語法結構:Process([group [, target [, name [, args [, kwargs]]]]])target:如果傳遞了函數的引用,可以讓這個子進程就執行函數中的代碼args:給 target 指定的函數傳遞的參數,以元組的形式進行傳遞kwargs:給 target 指定的函數傳遞參數,以字典的形式進行傳遞name:給進程設定一個名字,可以省略group:指定進程組,大多數情況下用不到Process 創建的實例對象的常用方法有:start():啟動子進程實例(創建子進程)is_alive():判斷進程子進程是否還在活著join(timeout):是否等待子進程執行結束,或者等待多少秒terminate():不管任務是否完成,立即終止子進程
Process 創建的實例對象的常用屬性:name:當前進程的別名,默認為 Process
-N,N 為從 1 開始遞增的整數pid:當前進程的 pid(進程號)

給子進程指定函數傳遞參數 Demo:
import os
from multiprocessing import Process import time def pro_func(name, age, **kwargs):   for i in range(5):     print("子進程正在運行中,name=%s, age=%d, pid=%d" %(name, age, os.getpid()))     print(kwargs)    time.sleep(0.2) if __name__ == '__main__': # 創建 Process 對象p = Process(target=pro_func, args=('小明',18), kwargs={'m': 20}) # 啟動進程p.start()time.sleep(1) # 1 秒鐘之后,立刻結束子進程p.terminate()p.join() 注意:進程間不共享全局變量。

?

進程之間的通信-Queue 在初始化 Queue()對象時,(例如 q=Queue(),若在括號中沒有指定最大可接受的消息數量,或數量為負值時,那么就代表可接受的消息數量沒有上限-直到內存的盡頭)
  Queue.qsize():返回當前隊列包含的消息數量。Queue.empty():如果隊列為空,返回 True,反之 False。Queue.full():如果隊列滿了,返回 True,反之 False。Queue.get([block[,timeout]]):獲取隊列中的一條消息,然后將其從隊列中移除,block 默認值為True。如果 block 使用默認值,且沒有設置 timeout(單位秒),消息列隊如果為空,此時程序將被阻塞(停在讀取狀態),直到從消息列隊讀到消息為止,如果設置了 timeout,則會等待 timeout 秒,若還 沒讀取到任何消息,則拋出
"Queue.Empty"異常;如果 block 值為 False,消息列隊如果為空,則會立刻拋出"Queue.Empty"異常;
  Queue.get_nowait():相當 Queue.get(False);Queue.put(item,[block[, timeout]]):將 item 消息寫入隊列,block 默認值為 True;如果 block 使用默認值,且沒有設置 timeout(單位秒),消息列隊如果已經沒有空間可寫入,此時程序將被阻塞(停在寫入狀態),直到從消息列隊騰出空間為止,如果設置了 timeout,則會等待 timeout 秒,若還沒空間,則拋出
"Queue.Full"異常;如果 block 值為 False,消息列隊如果沒有空間可寫入,則會立刻拋出"Queue.Full"異常;Queue.put_nowait(item):相當 Queue.put(item, False);

進程間通信 Demo: from multiprocessing import Process, Queue
import os, time, random
# 寫數據進程執行的代碼:
def write(q):
for value in ['A', 'B', 'C']:print('Put %s to queue...' % value)q.put(value)time.sleep(random.random()) # 讀數據進程執行的代碼:
def read(q):
while True:if not q.empty():value = q.get(True)print('Get %s from queue.' % value)time.sleep(random.random())else:break if __name__=='__main__':# 父進程創建 Queue,并傳給各個子進程:q = Queue()pw = Process(target=write, args=(q,))pr = Process(target=read, args=(q,))# 啟動子進程 pw,寫入:pw.start()# 等待 pw 結束:pw.join()# 啟動子進程 pr,讀取:pr.start()pr.join()# pr 進程里是死循環,無法等待其結束,只能強行終止:print('')print('所有數據都寫入并且讀完') 進程池 Pool # -*- coding:utf-8 -*- from multiprocessing
import Poolimport os, time, randomdef worker(msg):t_start = time.time()print("%s 開始執行,進程號為%d" % (msg,os.getpid()))# random.random()隨機生成 0~1 之間的浮點數time.sleep(random.random()*2)t_stop = time.time()print(msg,"執行完畢,耗時%0.2f" % (t_stop-t_start)) po = Pool(3) # 定義一個進程池,最大進程數 3for i in range(0,10):# Pool().apply_async(要調用的目標,(傳遞給目標的參數元祖,))# 每次循環將會用空閑出來的子進程去調用目標po.apply_async(worker,(i,)) print("----start----") po.close() # 關閉進程池,關閉后 po 不再接收新的請求 po.join() # 等待 po 中所有子進程執行完成,必須放在 close 語句之后 print("-----end-----")

?

multiprocessing.Pool 常用函數解析:
  apply_async(func[, args[, kwds]]) :使用非阻塞方式調用 func(并行執行,堵塞方式必須等待上一個進程退出才能執行下一個進程),args 為傳遞給 func 的參數列表,kwds 為傳遞給 func的關鍵字參數列表;
  close():關閉 Pool,使其不再接受新的任務;
  terminate():不管任務是否完成,立即終止;
  join():主進程阻塞,等待子進程的退出, 必須在 close 或 terminate 之后使用;

進程池中使用 Queue
如果要使用 Pool 創建進程,就需要使用 multiprocessing.Manager()中的 Queue(),而不是multiprocessing.Queue(),否則會得到一條如下的錯誤信息:
RuntimeError: Queue objects should only be shared between processes through?inheritance

from multiprocessing
import Manager,Poolimport os,time,random def reader(q):print("reader 啟動(%s),父進程為(%s)" % (os.getpid(), os.getppid()))for i in range(q.qsize()):print("reader 從 Queue 獲取到消息:%s" % q.get(True)) def writer(q):print("writer 啟動(%s),父進程為(%s)" % (os.getpid(), os.getppid()))for i in "itcast":q.put(i) if __name__=="__main__":print("(%s) start" % os.getpid())q = Manager().Queue() # 使用 Manager 中的 Queuepo = Pool()po.apply_async(writer, (q,)) time.sleep(1) # 先讓上面的任務向 Queue 存入數據,然后再讓下面的任務開始從中取數據 po.apply_async(reader, (q,))po.close()po.join()print("(%s) End" % os.getpid())

?

?

2. 談談你對多進程,多線程,以及協程的理解,項目是否用?這個問題被問的概率相當之大,其實多線程,多進程,在實際開發中用到的很少,除非是那些對項目性能要求特別高的,有的開發工作幾年了,也確實沒用過,你可以這么回答,給他扯扯什么是進程, 線程(cpython 中是偽多線程)的概念就行,
實在不行你就說你之前寫過下載文件時,用過多線程技術,或者業余時間用過多線程寫爬蟲,提升效率。 進程:一個運行的程序(代碼)就是一個進程,沒有運行的代碼叫程序,進程是系統資源分配的最小單位,進程擁有自己獨立的內存空間,所以進程間數據不共享,開銷大。 線程:調度執行的最小單位,也叫執行路徑,不能獨立存在,依賴進程存在一個進程至少有一個線程,叫主線程,而多個線程共享內存(數據共享,共享全局變量),從而極大地提高了程序的運行效率。
協程:是一種用戶態的輕量級線程,協程的調度完全由用戶控制。協程擁有自己的寄存器上下文和棧。 協程調度切換時,將寄存器上下文和棧保存到其他地方,在切回來的時候,恢復先前保存的寄存器上下文和棧,
直接操作棧則基本沒有內核切換的開銷,可以不加鎖的訪問全局變量,所以上下文的切換非常快。
3. 什么是多線程競爭?線程是非獨立的,同一個進程里線程是數據共享的,當各個線程訪問數據資源時會出現競爭狀態即:數據幾乎同步會被多個線程占用,造成數據混亂,即所謂的線程不安全 那么怎么解決多線程競爭問題?-- 鎖。鎖的好處: 確保了某段關鍵代碼(共享數據資源)只能由一個線程從頭到尾完整地執行,能解決多線程資源競爭下的原子操作問題。 鎖的壞處: 阻止了多線程并發執行,包含鎖的某段代碼實際上只能以單線程模式執行,效率就大大地下降了
鎖的致命問題:死鎖。
4. 解釋一下什么是鎖,有哪幾種鎖? 鎖(Lock)是 Python 提供的對線程控制的對象。有互斥鎖、可重入鎖。5. 什么是死鎖呢? 若干子線程在系統資源競爭時,都在等待對方對某部分資源解除占用狀態,結果是誰也不愿先解鎖,互相干等著,程序無法執行下去,這就是死鎖。 GIL 鎖(有時候,面試官不問,你自己要主動說,增加 b 格,盡量別一問一答的尬聊,不然最后等到的一句話就是:你還有什么想問的么?) GIL 鎖 全局解釋器鎖(只在 cpython 里才有) 作用:限制多線程同時執行,保證同一時間只有一個線程執行,所以 cpython 里的多線程其實是偽多線程! 所以 Python 里常常使用協程技術來代替多線程,協程是一種更輕量級的線程, 進程和線程的切換時由系統決定,而協程由我們程序員自己決定,而模塊 gevent 下切換是遇到了耗時操作才會切換。 三者的關系:進程里有線程,線程里有協程。6.什么是線程安全,什么是互斥鎖? 每個對象都對應于一個可稱為" 互斥鎖" 的標記,這個標記用來保證在任一時刻,只能有一個線程訪問該對象。 同一個進程中的多線程之間是共享系統資源的,多個線程同時對一個對象進行操作,一個線程操作尚未結束,另一個線程已經對其進行操作,導致最終結果出現錯誤,此時需要對被操作對象添加互斥鎖, 保證每個線程對該對象的操作都得到正確的結果。

7.說說下面幾個概念:同步,異步,阻塞,非阻塞? 同步(IO):多個任務之間有先后順序執行,一個執行完下個才能執行。 異步:多個任務之間沒有先后順序,可以同時執行有時候一個任務可能要在必要的時候獲取另一個同時執行的任務的結果,這個就叫回調!
阻塞(函數調用的方式):如果卡住了調用者,調用者不能繼續往下執行,就是說調用者阻塞了。
非阻塞:如果不會卡住,可以繼續執行,就是說非阻塞的。 同步異步相對于多任務而言,阻塞非阻塞相對于代碼執行而言。

?

?

8. 什么是僵尸進程和孤兒進程?怎么避免僵尸進程? 孤兒進程:父進程退出,子進程還在運行的這些子進程都是孤兒進程,孤兒進程將被 init 進程(進程號為 1)所收養,并由 init 進程對它們完成狀態收集工作。 僵尸進程:進程使用 fork 創建子進程,如果子進程退出,而父進程并沒有調用 wait 或 waitpid 獲取子進程的狀態信息,那么子進程的進程描述符仍然保存在系統中的這些進程是僵尸進程。 避免僵尸進程的方法:1. fork 兩次用孫子進程去完成子進程的任務;2. 用 wait()函數使父進程阻塞;3. 使用信號量,在 signal handler 中調用 waitpid,這樣父進程不用阻塞。
9. Python 中的進程與線程的使用場景? 多進程適合在 CPU 密集型操作(cpu 操作指令比較多,如位數多的浮點運算)。多線程適合在 IO 密集型操作(讀寫數據操作較多的,比如爬蟲)。10. 線程是并發還是并行,進程是并發還是并行? 線程是并發,進程是并行; 進程之間相互獨立,是系統分配資源的最小單位,同一個線程中的所有線程共享資源。11. 并行(parallel)和并發(concurrency)? 并行:同一時刻多個任務同時在(多個cpu上)運行。 并發:在同一時間間隔內多個任務都在(一個cpu)運行,但是并不會在同一時刻同時運行,存在交替執行的情況。 實現并行的庫有:multiprocessing 實現并發的庫有:threading 程序需要執行較多的讀寫、請求和回復任務的需要大量的 IO 操作,IO 密集型操作使用并發更好。 CPU 運算量大的程序程序,使用并行會更好。12. IO 密集型和CPU 密集型區別? IO 密集型:系統運作,大部分的狀況是 CPU 在等 I/O (硬盤/內存)的讀/寫。 CPU 密集型:大部份時間用來做計算、邏輯判斷等 CPU 動作的程序稱之 CPU 密集型。

?

?

?

轉載于:https://www.cnblogs.com/wenyule/articles/10461486.html

總結

以上是生活随笔為你收集整理的bd3.2 Python高级的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。