同志們好,今天帶著大家一起來複習python中的基礎問題,我們都知道python屬於解釋性語言,效率也就相對其它語言來說較低一些,這個較低只是運行稍微低些,但是呢,在很多場景買這些都是微不足道的
憑藉著語法的易於理解和學習,可以在短時間內完成更多工作,開發效率也會變得更高
同時,python自帶了各種現成的函式庫,供我們在開發程式中使用,python也比較容易維護
Python為我們提供了非常完善的基礎程式碼庫,涵蓋了網路、檔案、GUI、資料庫、文字等大量內容,被形象化地稱作「內建電池(batteries included)」。用Python開發,許多功能不必從零編寫,直接使用現成的即可。
除了內建的函式庫外,Python還有大量的第三方函式庫,也就是別人開發的,供你直接使用的東西。當然,如果你開發的程式碼通過很好的封裝,也可以作為第三方函式庫給別人使用。
generator,有兩種產生生成器物件的方式:一種是列表產生式加括號:
g1 = (x for x in range(10) )
一種是在函數定義中包含yield關鍵字:
def fib(max): n, a, b = 0, 0, 1 while n < max:yield b a, b = b, a + b n = n + 1 return 'done'g2 = fib(8)
# 對於generator物件g1和g2,可以透過next(g1)不斷得到下一個元素的值,如果沒有更多的元素,就會報錯StopIteration
也可以透過for迴圈得到元素的值。
生成器的好處是不用佔用很多內存,只需要在用的時候計算元素的值就行了。
Python中可以用於for循環的,叫做可迭代Iterable,包括list/set/tuple/str/dict等資料結構以及生成器;可以用以下語句判斷一個對象是否是可迭代的:
from collections import Iterableisinstance(x, Iterable)
迭代器Iterator,是指可以被next()函數呼叫並不斷返回下一個值,直到StopIteration;生成器都是Iterator,而列表等資料結構不是;
可以透過以下語句將list變成Iterator:
iter([1,2,3,4,5])
#產生器都是Iterator,但迭代器不一定是生成器。
List: 本質是順序表,只不過每次表的擴容都是指數級,所以動態增刪資料時,表並不會頻繁改變物理結構,同時受益於順序表遍歷的高效性(透過角標配合表頭物理位址,計算目標元素的位置),使得python的list綜合性能比較優秀
dict: 本質上是順序表,不過每個元素儲存位置的角標,不是又插入順序決定的,而是由key經過hash演算法和其他機制,動態生成的,即key透過hash散列,生成value應該儲存的位置,然後再去存儲這個value;所以dict的查詢時間複雜度是o(1);
因此,dict的key只能為可hash的對象,即不可變型別;
Python中有一個被稱為Global Interpreter Lock(GIL)的東西,它會確保任何時候你的多個執行緒中,只有一個被執行。
執行緒的執行速度非常之快,會讓你誤以為執行緒是並行執行的,但是實際上都是輪流執行。經過GIL這一道關卡處理,會增加執行的開銷。
可以透過多進程實現多核心任務。
#print在py3裡是一個函數,在py2裡只是一個關鍵字
py3檔案的預設編碼是utf8,py2檔案的預設編碼是ascii
#py3的str是unicode字串,而py2的str是bytes
py3的range()傳回一個可迭代對象,py2的range()傳回一個列表,xrange()傳回一個可迭代對象,py3的除法回傳float,py2的除法回傳int
可變物件: list,dict,set
不可變物件: bool,int,float,tuple,str…
可迭代對象類,必須自訂__iter__()魔法方法,range,list類的實例化物件都是可迭代物件
迭代器類,必須自訂__iter__()和_ _next__()魔法方法,用iter()函數可以建立可迭代物件的迭代器
可以保存外部函数内的变量,不会随着外部函数调用完而销毁
什么是装饰器?
装饰器是一个接收函数作为参数的闭包函数
它可以在不修改函数内部源代码的情况下,给函数添加额外的功能
import time def calc_time(func): def inner(): t1 = time.time() func() t2 = time.time() print('cost time: {}s'.format(t2-t1)) return inner
元类是创建类的类,type还有继承自type的类都是元类
作用: 在类定义时(new, init)和 类实例化时(call) 可以添加自定义的功能
使用场景: ORM框架中创建一个类就代表数据库中的一个表,但是定义这个类时为了统一需要把里面的类属性全部改为小写,这个时候就要用元类重写new方法,把attrs字典里的key转为小写
全局解释器锁(Global Interpreter Lock)是计算机程序设计语言解释器用于同步线程的一种机制,它使得任何时刻仅有一个线程在执行。
即便在多核处理器上,使用 GIL 的解释器也只允许同一时间执行一个线程,常见的使用 GIL 的解释器有CPython与Ruby MRI。可以看到GIL并不是Python独有的特性,是解释型语言处理多线程问题的一种机制而非语言特性。
单核时代高效利用CPU, 针对解释器级别的数据安全(不是thread-safe 线程安全)。首先需要明确的是GIL并不是Python的特性,它是在实现Python解析器(CPython)时所引入的一个概念。
当Python虚拟机的线程想要调用C的原生线程需要知道线程的上下文,因为没有办法控制C的原生线程的执行,所以只能把上下文关系传给原生线程,同理获取结果也是线 程在python虚拟机这边等待。那么要执行一次计算操作,就必须让执行程序的线程组串行执行。
展开 GIL锁加在解释器一层,也就是说Python调用的Cython解释器上加了GIL锁,因为你python调用的所有线程都是原生线程。原生线程是通过C语言提供原生接口,相当于C语言的一个函数。
你一调它,你就控制不了了它了,就必须等它给你返回结果。只要已通过python虚拟机 ,再往下就不受python控制了,就是C语言自己控制了。
加在Python虚拟机以下加不上去,只能加在Python解释器这一层。
python2.x和3.x都是在执行IO操作的时候,强制释放GIL,使其他线程有机会执行程序。
Python2.x Python使用计数器ticks计算字节码,当执行100个字节码的时候强制释放GIL,其他线程获取GIL继续执行。ticks可以看作是Python自己的计数器,专门作用于GIL,释放后归零,技术可以调整。
Python3.x Python使用计时器,执行时间达到阈值后,当前线程释放GIL。总体来说比Python3.x对CPU密集型任务更好,但是依然没有解决问题。
简单来说,lambda表达式通常是当你需要使用一个函数,但是又不想费脑袋去命名一个函数的时候使用,也就是通常所说的匿名函数。
lambda表达式一般的形式是:关键词lambda后面紧接一个或多个参数,紧接一个冒号“:”,紧接一个表达式
赋值(=),就是创建了对象的一个新的引用,修改其中任意一个变量都会影响到另一个。
浅拷贝 copy.copy:创建一个新的对象,但它包含的是对原始对象中包含项的引用(如果用引用的方式修改其中一个对象,另外一个也会修改改变)
深拷贝:创建一个新的对象,并且递归的复制它所包含的对象(修改其中一个,另外一个不会改变){copy模块的deep.deepcopy()函数}
以上是我們一起聊聊 Python 八股文的詳細內容。更多資訊請關注PHP中文網其他相關文章!