国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

流暢的python讀書(shū)筆記-第八章-對(duì)象引用、可變性和垃圾回收

zgbgx / 1846人閱讀

摘要:運(yùn)算符比較兩個(gè)對(duì)象的標(biāo)識(shí)函數(shù)返回對(duì)象標(biāo)識(shí)的整數(shù)表示。實(shí)際上,每個(gè)對(duì)象都會(huì)統(tǒng)計(jì)有多少引用指向自己。對(duì)象被銷(xiāo)毀了,調(diào)用了回調(diào),的值變成了。當(dāng)對(duì)象的引用數(shù)量歸零后,垃圾回收程序會(huì)把對(duì)象銷(xiāo)毀。引用的目標(biāo)對(duì)象稱為所指對(duì)象。

對(duì)象不是個(gè)盒子

class Gizmo:
    def __init__(self):
        print("Gizmo id: %d" % id(self))

x = Gizmo()
print(x)

y = Gizmo() * 10
print(y)

print(dir())
? 輸出的 Gizmo id: ... 是創(chuàng)建 Gizmo 實(shí)例的副作用。
? 在乘法運(yùn)算中使用 Gizmo 實(shí)例會(huì)拋出異常。
? 這里表明,在嘗試求積之前其實(shí)會(huì)創(chuàng)建一個(gè)新的 Gizmo 實(shí)例。
? 但是,肯定不會(huì)創(chuàng)建變量 y,因?yàn)樵趯?duì)賦值語(yǔ)句的右邊進(jìn)行求值時(shí)拋出了異常。
 為了理解 Python 中的賦值語(yǔ)句,應(yīng)該始終先讀右邊。對(duì)象在右邊創(chuàng)建或獲取,在此之后左邊的變量才會(huì)綁定到對(duì)象上,
標(biāo)識(shí)、相等性和別名
longe = {"name": "longe", "born": 1993}
liang = longe
print(liang is longe)

print(id(liang), id(longe))

longe["balance"] = 950

print(liang)

## 冒充的longe信息

other  = {"name": "longe", "born": 1993, "balance": 950}
print(other)

print(other is longe)

? liang 是 longe 的別名。
? is 運(yùn)算符和 id 函數(shù)確認(rèn)了這一點(diǎn)。
? 向 liang 中添加一個(gè)元素相當(dāng)于向 longe 中添加一個(gè)元素。

在那段代碼中,liang 和 longe 是別名,即兩個(gè)變量綁定同一個(gè)對(duì)象。
而 other 不是 longe 的別名,因?yàn)槎呓壎ǖ氖遣煌膶?duì)象。

other 和longe 綁定的對(duì)象具有相同的值(== 比較的就是值),但是它們的標(biāo)識(shí)不同。

每個(gè)變量都有標(biāo)識(shí)、類(lèi)型和值。對(duì)象一旦創(chuàng)建,它的標(biāo)識(shí)絕不會(huì)變;

你可以把標(biāo)識(shí)理解為對(duì)象在內(nèi)存中的地址。

is 運(yùn)算符比較兩個(gè)對(duì)象的標(biāo)識(shí);

id() 函數(shù)返回對(duì)象標(biāo)識(shí)的整數(shù)表示。

在==和is之間選擇

== 運(yùn)算符比較兩個(gè)對(duì)象的值(對(duì)象中保存的數(shù)據(jù)),而 is 比較對(duì)象的標(biāo)識(shí)。

is 運(yùn)算符比 == 速度快,因?yàn)樗荒苤剌d,所以 Python 不用尋找并調(diào)用特殊方法,而是 直接比較兩個(gè)整數(shù) ID

eq 方法,會(huì)考慮對(duì)象屬性的值。相等性測(cè)試可能涉及大量處理工作,例如,比較大型集合或嵌套層級(jí)深的結(jié)構(gòu)時(shí)。

元組的相對(duì)不可變性

元組的不可變性其實(shí)是指 tuple 數(shù)據(jù)結(jié)構(gòu)的物理內(nèi)容(即保存的引用)不可變,與引用的對(duì)象無(wú)關(guān)

元組的值會(huì)隨著引用的可變對(duì)象的變化而變。

元組中不可變的是元素的標(biāo)識(shí)。內(nèi)存地址

>>> t1 = (1, 2, [30, 40]) ?
>>> t2 = (1, 2, [30, 40]) ?
>>> t1 == t2 ?
True
>>> id(t1[-1]) ?
4302515784
>>> t1[-1].append(99) ?
>>> t1
(1, 2, [30, 40, 99])
>>> id(t1[-1]) ?
4302515784
>>> t1 == t2 ?
False
基礎(chǔ)理解!!!還是可以的
默認(rèn)淺復(fù)制
>>> l1 = [3, [55, 44], (7, 8, 9)]
>>> l2 = list(l1) ?
>>> l2
[3, [55, 44], (7, 8, 9)]
>>> l2 == l1 ?
True
>>> l2 is l1 ?
False

然而,構(gòu)造方法或 [:] 做的是淺復(fù)制(即復(fù)制了最外層容器,副本中的元素是源容器中
元素的引用)。如果所有元素都是不可變的,那么這樣沒(méi)有問(wèn)題,還能節(jié)省內(nèi)存。

為任意對(duì)象做深復(fù)制和淺復(fù)制
import copy
class Bus:
    def __init__(self, passengers=None):
        if passengers is None:
            self.passengers = []
        else:
            self.passengers = list(passengers)

    def pick(self, name):
        self.passengers.append(name)

    def drop(self, name):
        self.passengers.remove(name)


bus1 = Bus(["Alice", "Bill", "Claire", "David"])
bus2 = copy.copy(bus1)
bus3 = copy.deepcopy(bus1)

print(id(bus1), id(bus2), id(bus3))

bus1.drop("Bill")
print(bus2.passengers)

print(id(bus1.passengers), id(bus2.passengers), id(bus3.passengers))

print(bus3.passengers)

? 審查 passengers 屬性后發(fā)現(xiàn),bus1 和 bus2 共享同一個(gè)列表對(duì)象,因?yàn)?bus2 是
bus1 的淺復(fù)制副本。
? bus3 是 bus1 的深復(fù)制副本,因此它的 passengers 屬性指代另一個(gè)列表。

注意,一般來(lái)說(shuō),深復(fù)制不是件簡(jiǎn)單的事。如果對(duì)象有循環(huán)引用,那么這個(gè)樸素的算法會(huì)進(jìn)入無(wú)限循環(huán)
深復(fù)制
>>> a = [10, 20]
>>> b = [a, 30]
>>> a.append(b)
>>> a
[10, 20, [[...], 30]]
>>> from copy import deepcopy
>>> c = deepcopy(a)
>>> c
[10, 20, [[...], 30]]
深復(fù)制有時(shí)可能太深了。例如,對(duì)象可能會(huì)引用不該復(fù)制的外部資源或單例值。我們可以實(shí)現(xiàn)特殊方法 __copy__() 和 __deepcopy__(),控制 copy 和 deepcopy 的行為
函數(shù)的參數(shù)作為引用時(shí)

共享傳參指函數(shù)的各個(gè)形式參數(shù)獲得實(shí)參中各個(gè)引用的副本。也就是說(shuō),函數(shù)內(nèi)部的形參
是實(shí)參的別名。

def f(a, b):
    a += b
    return a


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

print(f(a, b))
print(a, b)

這里變量全都是引用,無(wú)論局部變量還是全局.
所以上面案例中,a會(huì)變化

不要使用可變類(lèi)型作為參數(shù)的默認(rèn)值
class HauntedBus:
    """備受幽靈乘客折磨的校車(chē)"""
    def __init__(self, passengers=[]):  #別使用這種可變類(lèi)型 作為默認(rèn)參數(shù)
        self.passengers = passengers 
防御性編程(對(duì)待可變類(lèi)型)
class TwilightBus:
    """正常的校車(chē)"""

    def __init__(self, passengers=None):

        if passengers is None:
            self.passengers = []
        else:
            self.passengers = list(passengers) ##這里會(huì)產(chǎn)生副本(可以理解為深拷貝)

    def pick(self, name):
        self.passengers.append(name)

    def drop(self, name):
        self.passengers.remove(name)


bus1 = TwilightBus(("sfs", "sdf"))
bus2 = TwilightBus(["sdfsdfsfd111"])

bus1.pick("ppxia")
bus1.drop("sfs")
print(bus1.passengers)

bus2.drop("sdfsdfsfd111")
print(bus2.passengers)
http://www.pythontutor.com/vi...
盡量別用可變類(lèi)型做默認(rèn)參數(shù)值, 實(shí)在要用,必須使其產(chǎn)生副本
del和垃圾回收

有個(gè) del 特殊方法,但是它不會(huì)銷(xiāo)毀實(shí)例,不應(yīng)該在代碼中調(diào)用。

即將銷(xiāo)毀實(shí)例時(shí),Python 解釋器會(huì)調(diào)用 del 方法,給實(shí)例最后的機(jī)會(huì),釋放外資源。

自己編寫(xiě)的代碼很少需要實(shí)現(xiàn) del 代碼,有些 Python 新手會(huì)花時(shí)間實(shí)現(xiàn),但卻吃力不討好,因?yàn)?del 很難用對(duì)。

垃圾計(jì)數(shù)器

在 CPython 中,垃圾回收使用的主要算法是引用計(jì)數(shù)。

實(shí)際上,每個(gè)對(duì)象都會(huì)統(tǒng)計(jì)有多少引用指向自己。

當(dāng)引用計(jì)數(shù)歸零時(shí),對(duì)象立即就被銷(xiāo)毀:CPython 會(huì)在對(duì)象上調(diào)用__del__ 方法(如果定義了),然后釋放分配給對(duì)象的內(nèi)存。

為了演示對(duì)象生命結(jié)束時(shí)的情形,示例 8-16 使用 weakref.finalize 注冊(cè)一個(gè)回調(diào)函數(shù),在銷(xiāo)毀對(duì)象時(shí)調(diào)用。
>>> import weakref
>>> s1 = {1, 2, 3}
>>> s2 = s1 ?
>>> def bye(): ?
... print("Gone with the wind...")
...
>>> ender = weakref.finalize(s1, bye) ?
>>> ender.alive ?
True
>>> del s1
>>> ender.alive ?
True
>>> s2 = "spam" ?
Gone with the wind...
>>> ender.alive
False

? 如前所述,del 不刪除對(duì)象,而是刪除對(duì)象的引用。
? 重新綁定最后一個(gè)引用 s2,讓 {1, 2, 3} 無(wú)法獲取。對(duì)象被銷(xiāo)毀了,調(diào)用了 bye 回
調(diào),ender.alive 的值變成了 False。

 弱引用

正是因?yàn)橛幸茫瑢?duì)象才會(huì)在內(nèi)存中存在。當(dāng)對(duì)象的引用數(shù)量歸零后,垃圾回收程序會(huì)把對(duì)象銷(xiāo)毀。但是,有時(shí)需要引用對(duì)象,而不讓對(duì)象存在的時(shí)間超過(guò)所需時(shí)間。

弱引用不會(huì)增加對(duì)象的引用數(shù)量。引用的目標(biāo)對(duì)象稱為所指對(duì)象(referent)。因此我們說(shuō),弱引用不會(huì)妨礙所指對(duì)象被當(dāng)作垃圾回收。

弱引用在緩存應(yīng)用中很有用,因?yàn)槲覀儾幌雰H因?yàn)楸痪彺嬉弥冀K保存緩存對(duì)象。

弱引用是可調(diào)用的對(duì)象,返回的是被引用的對(duì)象;
>>> import weakref
>>> a_set = {0, 1}
>>> wref = weakref.ref(a_set) ?
>>> wref

>>> wref() ?
{0, 1}
>>> a_set = {2, 3, 4} ?
>>> wref() ?
{0, 1}
>>> wref() is None ?
False
>>> wref() is None ?
True

? 調(diào)用 wref() 返回的是被引用的對(duì)象,{0, 1}。因?yàn)檫@是控制臺(tái)會(huì)話,所以 {0, 1}
會(huì)綁定給 _ 變量。
? a_set 不再指代 {0, 1} 集合,因此集合的引用數(shù)量減少了。但是 _ 變量仍然指代
它。
? 調(diào)用 wref() 依舊返回 {0, 1}。
? 計(jì)算這個(gè)表達(dá)式時(shí),{0, 1} 存在,因此 wref() 不是 None。但是,隨后 _ 綁定到結(jié)
果值 False。現(xiàn)在 {0, 1} 沒(méi)有強(qiáng)引用了。
? 因?yàn)?{0, 1} 對(duì)象不存在了,所以 wref() 返回 None。

弱引用到此為止,用到再來(lái)查 page 289 總結(jié)

變量的不是盒子,是便利貼(就是c的指針)

==是值相等 is是(內(nèi)存地址相等)

默認(rèn)是淺復(fù)制,就內(nèi)存地址復(fù)制.深復(fù)制會(huì)有一些過(guò)深危險(xiǎn)(可以重寫(xiě)特殊方法 __copy__() 和 __deepcopy__())

盡量別用可變類(lèi)型做默認(rèn)參數(shù)值, 實(shí)在要用,必須使其產(chǎn)生副本

實(shí)際上,每個(gè)對(duì)象都會(huì)統(tǒng)計(jì)有多少引用指向自己。 Cpython中, 當(dāng)引用計(jì)數(shù)歸零時(shí),對(duì)象立即就被銷(xiāo)毀:CPython會(huì)在對(duì)象上調(diào)用__del__ 方法(如果定義了),然后釋放分配給對(duì)象的內(nèi)存

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/41681.html

相關(guān)文章

  • 讀書(shū)筆記之深入理解Java虛擬機(jī)

    摘要:前言本文內(nèi)容基本摘抄自深入理解虛擬機(jī),以供復(fù)習(xí)之用,沒(méi)有多少參考價(jià)值。此區(qū)域是唯一一個(gè)在虛擬機(jī)規(guī)范中沒(méi)有規(guī)定任何情況的區(qū)域。堆是所有線程共享的內(nèi)存區(qū)域,在虛擬機(jī)啟動(dòng)時(shí)創(chuàng)建。虛擬機(jī)上把方法區(qū)稱為永久代。 前言 本文內(nèi)容基本摘抄自《深入理解Java虛擬機(jī)》,以供復(fù)習(xí)之用,沒(méi)有多少參考價(jià)值。想要更詳細(xì)了解請(qǐng)參考原書(shū)。 第二章 1.運(yùn)行時(shí)數(shù)據(jù)區(qū)域 showImg(https://segment...

    jaysun 評(píng)論0 收藏0
  • 《java 8 實(shí)戰(zhàn)》讀書(shū)筆記 -八章 重構(gòu)、測(cè)試調(diào)試

    摘要:通常,這種模式是通過(guò)定義一個(gè)代表處理對(duì)象的抽象類(lèi)來(lái)實(shí)現(xiàn)的,在抽象類(lèi)中會(huì)定義一個(gè)字段來(lái)記錄后續(xù)對(duì)象。工廠模式使用表達(dá)式第章中,我們已經(jīng)知道可以像引用方法一樣引用構(gòu)造函數(shù)。 一、為改善可讀性和靈活性重構(gòu)代碼 1.改善代碼的可讀性 Java 8的新特性也可以幫助提升代碼的可讀性: 使用Java 8,你可以減少冗長(zhǎng)的代碼,讓代碼更易于理解 通過(guò)方法引用和Stream API,你的代碼會(huì)變得更...

    gclove 評(píng)論0 收藏0
  • [譯] 與 Python 無(wú)縫集成——基本特殊方法 4

    摘要:當(dāng)引用計(jì)數(shù)為零,則不再需要該對(duì)象且可以銷(xiāo)毀。這表明當(dāng)變量被刪除時(shí)引用計(jì)數(shù)正確的變?yōu)榱恪7椒ㄖ荒茉谘h(huán)被打破后且引用計(jì)數(shù)已經(jīng)為零時(shí)調(diào)用。這兩步的過(guò)程允許引用計(jì)數(shù)或垃圾收集刪除已引用的對(duì)象,讓弱引用懸空。這允許在方法設(shè)置對(duì)象屬性值之前進(jìn)行處理。 注:原書(shū)作者 Steven F. Lott,原書(shū)名為 Mastering Object-oriented Python __del__()方法 ...

    Allen 評(píng)論0 收藏0
  • Python學(xué)習(xí)之路27-對(duì)象引用變性垃圾回收

    摘要:函數(shù)的參數(shù)作為引用時(shí)唯一支持的參數(shù)傳遞模式是共享傳參,它指函數(shù)的形參獲得實(shí)參中各個(gè)引用的副本,即形參是實(shí)參的別名。而在上面這個(gè)例子中,類(lèi)的屬性實(shí)際上是形參所指向的對(duì)象所指對(duì)象,的別名。 《流暢的Python》筆記本篇是面向?qū)ο髴T用方法的第一篇,一共六篇。本篇主要是一些概念性的討論,內(nèi)容有:Python中的變量,對(duì)象標(biāo)識(shí),值,別名,元組的某些特性,深淺復(fù)制,引用,函數(shù)參數(shù),垃圾回收,de...

    Batkid 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

zgbgx

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<