我對 Python 中的方法實作有些困惑。在這方面的任何幫助將不勝感激。
我發現這個密切相關的帖子非常有用,但沒有回答我的問題。
我的問題:Python 檔案中第 9.3.4 節最后一段中的以下陳述句對我來說不太清楚。
當參考實體的非資料屬性時,將搜索實體的類。如果名稱表示作為函式物件的有效類屬性,則通過打包(指向)實體物件和剛剛在抽象物件中一起找到的函式物件來創建方法物件:這就是方法物件。當使用引數串列呼叫方法物件時,會根據實體物件和引數串列構造一個新的引數串列,并使用這個新的引數串列呼叫函式物件。
我對檔案的初步理解與@vaughn-mcgill-adami 在他們的帖子中描述的非常相似:當類實體物件呼叫其方法物件時,將在類物件上搜索相應的函式物件。如果找到,則使用類實體物件作為第一個引數呼叫類物件擁有的該函式。
但是,經過一些編碼后,在我看來,我的理解可能不正確。原因是可以洗掉類物件。然而,呼叫方法物件仍然沒有問題,而將類實體物件從類物件傳遞給函式物件會導致錯誤,因為洗掉后將不再有類物件。
以下代碼片段旨在更好地解釋我的問題:
class myclass:
x=0
def inc(self):
self.x =1
print(self.x)
myobj = myclass()
type(myobj.inc) #output: method
type(myclass.inc) #output: function
# 1. calling method object multiple times
# 2. calling function object and passing the instance object multiple times
print(myobj.x)
for i in range(3):
myobj.inc()
for i in range(3):
myclass.inc(myobj)
#-------------
# output:
#-------------
# 0
# 1
# 2
# 3
# 4
# 5
# 6
#-------------
# deleting the class object
del myclass
# calling method object multiple times
for i in range(3):
myobj.inc()
#-------------
# output:
#-------------
# 7
# 8
# 9
#-------------
# calling function object and passing the instance object
for i in range(3):
myclass.inc(myobj)
#-------------
# output:
#-------------
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-177-86f094e96103> in <module>
1 for i in range(3):
----> 2 myclass.inc(myobj)
NameError: name 'myclass' is not defined
我從附加的代碼片段中的理解是,在實體化一個類物件之后,方法物件被附加到類實體物件上。方法物件和類實體物件將獨立于類物件。
以下是我從檔案中得到的一些歧義:
“...搜索實體的類”是什么意思?我相信它應該是“實體類物件”,但它似乎不是一個錯字,因為在下面的句子中它說“如果名稱表示一個有效的類屬性,它是一個函式物件......”。同樣,在這里我認為“方法物件”應該替換“函式物件”。
“...創建了一個方法物件...”。方法物件是在被呼叫后創建的,還是在創建類實體物件的同時?
“通過打包(指向)實體物件和剛剛找到的函式物件”。同樣,“函式物件”對我來說似乎不正確。
基本上,如果類物件被洗掉,就像在我的代碼片段中一樣,那么首先就沒有要搜索的類物件。也不會指向任何函式物件。
我很有可能在這里遺漏了一些東西。如果有人可以請指教,我將不勝感激。謝謝
uj5u.com熱心網友回復:
基本上,如果類物件被洗掉,就像在我的代碼片段中一樣,那么首先就沒有要搜索的類物件。也不會指向任何函式物件。
這是你的根本誤解。
del不洗掉物件。
確實,Python 語言沒有提供手動洗掉物件的方法(或手動管理記憶體,即它是一種記憶體管理語言)。
del從命名空間中洗掉名稱。
當您使用 時del myclass,您只需從該模塊的命名空間中洗掉該名稱。但是類物件仍然存在,一方面,它被該類的所有實體參考my_object.__class__,并且像任何其他物件一樣,只要對它的參考存在,它就會繼續存在。
因此,請考慮以下示例del:
>>> x = [1,2,3]
>>> y = x
>>> print(x is y)
True
>>> print(id(x), id(y))
140664200270464 140664200270464
>>> x.append(1337)
>>> x
[1, 2, 3, 1337]
>>> y
[1, 2, 3, 1337]
>>> del x
>>> print(y)
[1, 2, 3, 1337]
所以delx 沒有洗掉 object,它只是x從該命名空間中洗掉了名稱。所以如果我這樣做:
>>> print(x)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
del只能間接導致物件的洗掉,如果您從命名空間中洗掉的名稱是對該物件的最后一個參考,則該物件可用于垃圾收集(在 CPython 中,它使用參考計數作為主要的垃圾收集策略,它將被立即回收,但在其他實作中可能不是這樣,例如,JYthon,它使用 Java 運行時的垃圾收集器)。
該del宣告的一些相關檔案在這里:
洗掉名稱會從本地或全域名稱空間中洗掉該名稱的系結,具體取決于該名稱是否出現在同一代碼塊中的全域陳述句中。如果名稱未系結,則會引發 NameError 例外。
注意,另一部分,
屬性參考、訂閱和切片的洗掉傳遞給所涉及的主要物件;切片的洗掉通常等同于分配正確型別的空切片(但即使這也是由切片物件決定的)。
基本上是說像這樣的宣告
del obj[item]
被委托給
type(obj).__delitem__
即,它只是呼叫方法的糖。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/391619.html
