python內存優化函數 python內存機制

Python內存駐留機制

字符串駐留機制在許多面向對象編程語言中都支持,比如Java、python、Ruby、PHP等,它是一種數據緩存機制,對不可變數據類型使用同一個內存地址,有效的節省了空間,本文主要介紹Python的內存駐留機制。

十載的疏附網站建設經驗,針對設計、前端、開發、售后、文案、推廣等六對一服務,響應快,48小時及時工作處理。全網整合營銷推廣的優勢是能夠根據用戶設備顯示端的尺寸不同,自動調整疏附建站的顯示方式,使網站能夠適用不同顯示終端,在瀏覽器中調整網站的寬度,無論在任何一種瀏覽器上瀏覽網站,都能展現優雅布局與設計,從而大程度地提升瀏覽體驗。創新互聯從事“疏附網站設計”,“疏附網站推廣”以來,每個客戶項目都認真落實執行。

字符串駐留就是每個字符串只有一個副本,多個對象共享該副本,駐留只針對不可變數據類型,比如字符串,布爾值,數字等。在這些固定數據類型處理中,使用駐留可以有效節省時間和空間,當然在駐留池中創建或者插入新的內容會消耗一定的時間。

下面舉例介紹python中的駐留機制。

在Python對象及內存管理機制一文中介紹了python的參數傳遞以及以及內存管理機制,來看下面一段代碼:

知道結果是什么嗎?下面是執行結果:

l1和l2內容相同,卻指向了不同的內存地址,l2和l3之間使用等號賦值,所以指向了同一個對象。因為列表是可變對象,每創建一個列表,都會重新分配內存,列表對象是沒有“內存駐留”機制的。下面來看不可變數據類型的駐留機制。

在 Jupyter或者控制臺交互環境 中執行下面代碼:

執行結果:

可以發現a1和b1指向了不同的地址,a2和b2指向了相同的地址,這是為什么呢?

因為啟動時,Python 將一個 -5~256 之間整數列表預加載(緩存)到內存中,我們在這個范圍內創建一個整數對象時,python會自動引用緩存的對象,不會創建新的整數對象。

浮點型不支持:

如果上面的代碼在非交互環境,也就是將代碼作為python腳本運行的結果是什么呢?(運行環境為python3.7)

全為True,沒有明確的限定臨界值,都進行了駐留操作。這是因為使用不同的環境時,代碼的優化方式不同。

在 Jupyter或者控制臺交互環境 中:

滿足標識符命名規范的字符:

結果:

乘法獲取字符串(運行環境為python3.7)

結果:

在非交互環境中:

注意: 字符串是在編譯時進行駐留 ,也就是說,如果字符串的值不能在編譯時進行計算,將不會駐留。比如下面的例子:

在交互環境執行結果如下:

都指向不同的內存。

python 3.7 非交互環境執行結果:

發現d和e指向不同的內存,因為d和e不是在編譯時計算的,而是在運行時計算的。前面的 a = 'aa'*50 是在編譯時計算的。

除了上面介紹的python默認的駐留外,可以使用sys模塊中的intern()函數來指定駐留內容

結果:

使用intern()后,都指向了相同的地址。

本文主要介紹了python的內存駐留,內存駐留是python優化的一種策略,注意不同運行環境下優化策略不一樣,不同的python版本也不相同。注意字符串是在編譯時進行駐留。

--THE END--

python使用函數可以減小內存開支嗎

函數其實也就是封裝好的算法代碼,因為一些常用函數都經過開發者,用戶的多次測試優化,在python的開源環境下更是如此,所以大多時候比新手開發者自己寫的方法內存性能都有提升,但針對不同的需求,自己寫新的算法可能更優,并不絕對

Python中的10條冷門知識

下面時Python中一些不常見的冷門知識,感興趣的小伙伴不妨來學習一下。

1、省略號也是對象

… 這是省略號,在Python中,一切皆對象。它也不例外。在 Python 中,它叫做 Ellipsis 。在 Python 3 中你可以直接寫…來得到這玩意。

...

Ellipsis

type(...)

class 'ellipsis'

而在 Python2 中沒有…這個語法,只能直接寫Ellipsis來獲取。

Ellipsis

Ellipsis

type(Ellipsis)

type 'ellipsis'

它轉為布爾值時為真

bool(...)

True

最后,這東西是一個單例。

id(...)

4362672336

id(...)

4362672336

這東西有啥用呢?據說它是Numpy的語法糖,不玩 Numpy 的人,可以說是沒啥用的。

在網上只看到這個 用 … 代替 pass ,稍微有點用,但又不是必須使用的。

try:

1/0

except ZeroDivisionError:

...

2、增量賦值的性能更好

諸如 += 和 *= 這些運算符,叫做 增量賦值運算符。這里使用用 += 舉例,以下兩種寫法,在效果上是等價的。

# 第一種

a = 1 ; a += 1

# 第二種

a = 1; a = a + 1

+= 其背后使用的魔法方法是 iadd,如果沒有實現這個方法則會退而求其次,使用 add 。

這兩種寫法有什么區別呢?

用列表舉例 a += b,使用 add 的話就像是使用了a.extend(b),如果使用 add 的話,則是 a = a+b,前者是直接在原列表上進行擴展,而后者是先從原列表中取出值,在一個新的列表中進行擴展,然后再將新的列表對象返回給變量,顯然后者的消耗要大些。

所以在能使用增量賦值的時候盡量使用它。

3、and 和or 的取值順序

and 和 or 是我們再熟悉不過的兩個邏輯運算符。而我們通常只用它來做判斷,很少用它來取值。

如果一個or表達式中所有值都為真,Python會選擇第一個值,而and表達式則會選擇第二個。

(2 or 3) * (5 and 7)

14 # 2*7

4、修改解釋器提示符

import sys

sys.ps1

' '

sys.ps2

'... '

sys.ps2 = '---------------- '

sys.ps1 = 'Python編程時光'

Python編程時光for i in range(2):

---------------- print (i)

----------------

5、默認參數最好不為可變對象

函數的參數分三種

可變參數

默認參數

關鍵字參數

今天要說的是,傳遞默認參數時,新手很容易踩雷的一個坑。

先來看一個示例:

def func(item, item_list=[]):

item_list.append(item)

print(item_list)

func('iphone')

func('xiaomi', item_list=['oppo','vivo'])

func('huawei')

在這里,你可以暫停一下,思考一下會輸出什么?

思考過后,你的答案是否和下面的一致呢

['iphone']

['oppo', 'vivo', 'xiaomi']

['iphone', 'huawei']

如果是,那你可以跳過這部分內容,如果不是,請接著往下看,這里來分析一下。

Python 中的 def 語句在每次執行的時候都初始化一個函數對象,這個函數對象就是我們要調用的函數,可以把它當成一個一般的對象,只不過這個對象擁有一個可執行的方法和部分屬性。

對于參數中提供了初始值的參數,由于 Python 中的函數參數傳遞的是對象,也可以認為是傳地址,在第一次初始化 def 的時候,會先生成這個可變對象的內存地址,然后將這個默認參數 item_list 會與這個內存地址綁定。在后面的函數調用中,如果調用方指定了新的默認值,就會將原來的默認值覆蓋。如果調用方沒有指定新的默認值,那就會使用原來的默認值。

在這里插入圖片描述

6、訪問類中的私有方法

大家都知道,類中可供直接調用的方法,只有公有方法(protected類型的方法也可以,但是不建議)。也就是說,類的私有方法是無法直接調用的。

這里先看一下例子

class Kls():

def public(self):

print('Hello public world!')

def __private(self):

print('Hello private world!')

def call_private(self):

self.__private()

ins = Kls()

# 調用公有方法,沒問題

ins.public()

# 直接調用私有方法,不行

ins.__private()

# 但你可以通過內部公有方法,進行代理

ins.call_private()

既然都是方法,那我們真的沒有方法可以直接調用嗎?

當然有啦,只是建議你千萬不要這樣弄,這里只是普及,讓你了解一下。

# 調用私有方法,以下兩種等價

ins._Kls__private()

ins.call_private()

7、時有時無的切片異常

這是個簡單例子

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

print(my_list[5])

Traceback (most recent call last):

File "F:/Python Script/test.py", line 2, in module

print(my_list[5])

IndexError: list index out of range

來看看,如下這種寫法就不會報索引異常,執行my_list[5:],會返回一個新list:[]。

my_list = [1, 2, 3]

print(my_list[5:])

8、for 死循環

for 循環可以說是 基礎得不能再基礎的知識點了。但是如果讓你用 for 寫一個死循環,你會寫嗎?(問題來自群友 陳**)

這是個開放性的問題,在往下看之前,建議你先嘗試自己思考,你會如何解答。

好了,如果你還沒有思路,那就來看一下 一個海外 MIT 群友的回答:

for i in iter(int, 1):pass

是不是懵逼了。iter 還有這種用法?這為啥是個死循環?

這真的是個冷知識,關于這個知識點,你如果看中文網站,可能找不到相關資料。

還好你可以通過 IDE 看py源碼里的注釋內容,介紹了很詳細的使用方法。

原來iter有兩種使用方法,通常我們的認知是第一種,將一個列表轉化為一個迭代器。

而第二種方法,他接收一個 callable對象,和一個sentinel 參數。第一個對象會一直運行,直到它返回 sentinel 值才結束。

在這里插入圖片描述

那int 呢,這又是一個知識點,int 是一個內建方法。通過看注釋,可以看出它是有默認值0的。你可以在終端上輸入 int() 看看是不是返回0。

在這里插入圖片描述

由于int() 永遠返回0,永遠返回不了1,所以這個 for 循環會沒有終點。一直運行下去。

9、奇怪的字符串

字符串類型作為 Python 中最常用的數據類型之一,Python解釋器為了提高字符串使用的效率和使用性能,做了很多優化。

例如:Python 解釋器中使用了 intern(字符串駐留)的技術來提高字符串效率。

什么是 intern 機制?就是同樣的字符串對象僅僅會保存一份,放在一個字符串儲蓄池中,是共用的,當然,肯定不能改變,這也決定了字符串必須是不可變對象。

示例一

# Python2.7

a = "Hello_Python"

id(a)

32045616

id("Hello" + "_" + "Python")

32045616

# Python3.7

a = "Hello_Python"

id(a)

38764272

id("Hello" + "_" + "Python")

32045616

示例二

a = "MING"

b = "MING"

a is b

True

# Python2.7

a, b = "MING!", "MING!"

a is b

True

# Python3.7

a, b = "MING!", "MING!"

a is b

False

示例三

# Python2.7

'a' * 20 is 'aaaaaaaaaaaaaaaaaaaa'

True

'a' * 21 is 'aaaaaaaaaaaaaaaaaaaaa'

False

# Python3.7

'a' * 20 is 'aaaaaaaaaaaaaaaaaaaa'

True

'a' * 21 is 'aaaaaaaaaaaaaaaaaaaaa'

True

示例四

s1="hello"

s2="hello"

s1 is s2

True

# 如果有空格,默認不啟用intern機制

s1="hell o"

s2="hell o"

s1 is s2

False

# 如果一個字符串長度超過20個字符,不啟動intern機制

s1 = "a" * 20

s2 = "a" * 20

s1 is s2

True

s1 = "a" * 21

s2 = "a" * 21

s1 is s2

False

s1 = "ab" * 10

s2 = "ab" * 10

s1 is s2

True

s1 = "ab" * 11

s2 = "ab" * 11

s1 is s2

False

10、兩次return

我們都知道,try…finally… 語句的用法,不管 try 里面是正常執行還是報異常,最終都能保證finally能夠執行。

同時,我們又知道,一個函數里只要遇到 return 函數就會立馬結束。

基于以上這兩點,我們來看看這個例子,到底運行過程是怎么樣的?

def func():

... try:

... return 'try'

... finally:

... return 'finally'

...

func()

'finally'

驚奇的發現,在try里的return居然不起作用。

原因是,在try…finally…語句中,try中的return會被直接忽視,因為要保證finally能夠執行。

分享題目:python內存優化函數 python內存機制
瀏覽路徑:http://m.kartarina.com/article30/hgjpso.html

成都網站建設公司_創新互聯,為您提供服務器托管網站導航企業網站制作營銷型網站建設網站設計域名注冊

廣告

聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯

網站優化排名
主站蜘蛛池模板: 中日韩亚洲人成无码网站| 无码午夜人妻一区二区三区不卡视频| 无码人妻精品内射一二三AV| 无码丰满熟妇一区二区| 中文字幕日产无码| 精品人妻无码专区中文字幕| 曰韩人妻无码一区二区三区综合部 | 伊人无码精品久久一区二区| 国产成人无码a区在线观看视频免费| 国产日韩精品无码区免费专区国产| 亚洲av无码久久忘忧草| 国模吧无码一区二区三区| 久久亚洲中文无码咪咪爱| 无码AV中文一区二区三区| 国产亚洲精品无码专区| 成人麻豆日韩在无码视频| 精品国产a∨无码一区二区三区| 自拍偷在线精品自拍偷无码专区| 人妻在线无码一区二区三区| 99久久人妻无码精品系列蜜桃| 人妻少妇无码精品视频区| 国产成人精品无码专区| 无码射肉在线播放视频| 中字无码av电影在线观看网站| 色综合久久无码五十路人妻| 亚洲精品无码久久久久| 亚洲精品无码MV在线观看| 久久国产精品无码网站| 韩国免费a级作爱片无码| 亚洲AV无码乱码在线观看牲色| 久久AV无码精品人妻出轨| 久久美利坚合众国AV无码| 免费无码一区二区三区蜜桃大| 国产精品无码亚洲精品2021| 久久久无码精品人妻一区| 免费无码又爽又刺激聊天APP| 东京热一精品无码AV| 国产成人精品无码专区| 国内精品人妻无码久久久影院导航| 无码人妻一区二区三区免费视频| 无码毛片一区二区三区中文字幕|