摘要:在我的一個(gè)業(yè)務(wù)邏輯代碼中,我不幸需要編寫(xiě)以下類(lèi)這里我們用抽象的表示這是兩個(gè)沒(méi)有什么問(wèn)題的對(duì)象,不過(guò)在創(chuàng)建的實(shí)例時(shí),會(huì)讓自己的屬性指向一個(gè)的實(shí)例,而中的屬性又指向該實(shí)例所以我們可以像下面這樣訪問(wèn)這樣能夠使得擁有的控制權(quán),也同時(shí)使得擁有的控制權(quán)
在我的一個(gè)業(yè)務(wù)邏輯代碼中,我不幸需要編寫(xiě)以下類(lèi)(這里我們用抽象的A, B, C表示)
class A: value = 0 def __init__(self, b): self.b = b def set_1(self): self.value = 1 class B: def __init__(self): pass def reset(self): self.a = A(self)
這是兩個(gè)沒(méi)有什么問(wèn)題的對(duì)象,不過(guò)在創(chuàng)建B的實(shí)例時(shí),會(huì)讓自己的屬性a指向一個(gè)A的實(shí)例,而a中的屬性b又指向該B實(shí)例
所以我們可以像下面這樣訪問(wèn):
b = B() a = b.a assert b.a.b is b assert b.a.b.a is a
這樣能夠使得b擁有a的控制權(quán),也同時(shí)使得a擁有b的控制權(quán)。
但是當(dāng)我試圖用一個(gè)類(lèi)C來(lái)代理實(shí)例b時(shí),卻犯了一個(gè)錯(cuò)誤
class C: b = B() a = b.a def __init__(self): pass def read_a(self): return self.b.a.value c = C() assert c.read_a() == 0 c.a.set_1() assert c.read_a() == 1 c.b.reset() assert c.read_a() == 0 assert c.a == 0 # AssertionError
為什么這里我會(huì)腦子抽斷言 c.a == 0呢?
因?yàn)槲抑饔^地認(rèn)為這里實(shí)例b執(zhí)行了reset函數(shù),于是重新實(shí)例化了屬性b.a=A(self)
那么a在實(shí)例過(guò)程中,會(huì)讓a.value = 0
所以 c.b.a.value == 0
而我們的c.a = b.a
所以c.a.value == c.b.a.value == 0
幾乎完美的推理!!!
但是我忽略了,這里的c.a is not c.b.a !!!
原因如下:
假設(shè)一開(kāi)始實(shí)例化A, B 為 a1, b1
c.a -> a1
c.b -> b1
那么當(dāng)b1.reset() 的時(shí)候,a是重新實(shí)例化的一個(gè)A對(duì)象,用JAVA的話(huà)來(lái)說(shuō),就是重新new 了一個(gè)A
b1.a -> a2
故c.b.a == c.b1.a == a2
而c.a == a1
a1.value在a1.set_1()之后,賦值為 1
a2.value在b1.reset()之后,賦值為 0
所以斷言錯(cuò)誤
記錄這個(gè)錯(cuò)誤警告自己在今后的編碼過(guò)程中不要一味主觀地用數(shù)學(xué)觀點(diǎn),而要弄清楚具體對(duì)象。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/41083.html
摘要:靜下來(lái)想了想發(fā)現(xiàn)我犯了一個(gè)低級(jí)錯(cuò)誤。上面的代碼中函數(shù)是在這個(gè)函數(shù)閉包中申明的,在這個(gè)函數(shù)執(zhí)行完畢后,由于它被綁上了事件,引用并不為,所以沒(méi)有被回收。 最近寫(xiě)一個(gè)web應(yīng)用的圖片上傳功能,里面有這么個(gè)場(chǎng)景:點(diǎn)擊上傳按鈕,呼出file input框,選擇完圖片進(jìn)行前端壓縮然后上傳,完畢后將返回的圖片鏈接展示給用戶(hù)。這個(gè)功能很常見(jiàn),但是在這里卻翻了船,所以專(zhuān)門(mén)記錄一下這個(gè)bug。 我是這么寫(xiě)...
摘要:當(dāng)我執(zhí)行代碼首次失敗時(shí),我去網(wǎng)上搜尋答案,他們說(shuō),你這種實(shí)現(xiàn)模式,就在注冊(cè)服務(wù)時(shí),應(yīng)該注冊(cè)抽象類(lèi),而不是接口類(lèi)。 1、第一點(diǎn),首先說(shuō)明設(shè)計(jì)模式跟實(shí)現(xiàn)服務(wù)容器沒(méi)關(guān)系 之所以采用這個(gè)標(biāo)題,是因?yàn)樽约寒?dāng)初犯了這種錯(cuò)誤,希望新學(xué)laravel的人不要犯這種跟我一樣的錯(cuò)誤。 2、我定義了接口,同時(shí)抽象類(lèi)繼承接口,其他具體實(shí)現(xiàn)類(lèi)繼承抽象類(lèi)。 當(dāng)我執(zhí)行代碼首次失敗時(shí),我去網(wǎng)上搜尋答案,他們說(shuō),你這種...
摘要:粗暴地說(shuō)上面的過(guò)程就算是協(xié)程的基本概念。多線程和多進(jìn)程都是操作系統(tǒng)參與的調(diào)度,而協(xié)程是用戶(hù)自主實(shí)現(xiàn)的調(diào)度,協(xié)程的關(guān)鍵點(diǎn)實(shí)際上是用戶(hù)層實(shí)現(xiàn)自主調(diào)度,大概有翻身農(nóng)奴把歌唱的意思。 首先是,這是我第一次把公眾號(hào)文章復(fù)制粘貼到sf.gg來(lái)。 其次是,很久很久之前,我挖了一個(gè)yield的一個(gè)坑,自己挖的坑自己填,不然遲早會(huì)把自己埋掉。 最后是,如果想看之前那個(gè)坑,請(qǐng)發(fā)送yield給文章末尾的公眾...
摘要:我用的是內(nèi)核是,有些東西和不太一樣所以在起環(huán)境時(shí)遇到了一些沒(méi)見(jiàn)過(guò)的問(wèn)題。安裝與這倆我嘗試下載安裝官網(wǎng)上的包,但均以失敗告終,原因不明,還好自帶的軟件庫(kù)有最新版,可以很方便地進(jìn)行安裝。甚至還有檢查最新版本依賴(lài)的工具,省下了手動(dòng)更新的麻煩。 我用的linux是manjaro,內(nèi)核是arch,有些東西和ubantu,deepin不太一樣,所以在起環(huán)境時(shí)遇到了一些沒(méi)見(jiàn)過(guò)的問(wèn)題。 安裝nodej...
閱讀 954·2021-11-25 09:43
閱讀 2291·2019-08-30 15:55
閱讀 3153·2019-08-30 15:44
閱讀 2053·2019-08-29 16:20
閱讀 1453·2019-08-29 12:12
閱讀 1609·2019-08-26 12:19
閱讀 2283·2019-08-26 11:49
閱讀 1712·2019-08-26 11:42