我試圖填補我對 Python 物件和類如何作業的理解的空白。
裸object實體不以任何方式支持屬性分配:
> object().a = 5
# or
> setattr(object(), 'a', 5)
AttributeError: 'object' object has no attribute 'a'
我認為這是因為裸object實體不具有__dict__屬性:
> '__dict__' in dir(object())
False
然而,一個裸object實體確實有一個定義的__setattr__屬性,所以這讓我有點困惑:
> '__setattr__' in dir(object())
True
另一方面,常規空類的實體具有完全的屬性分配能力:
class B(object):
pass
> B().a = 5
> setattr(B(), 'a', 5)
我的問題是:如果直接繼承自,object實體和class B(object)實體之間的內在區別是什么允許前者具有可分配的屬性?Bobject
uj5u.com熱心網友回復:
的object()類就像蟒宇宙的基本顆粒,并且是基類(或結構單元),用于在Python所有物件(讀一切)。因此,所述行為是合乎邏輯的,因為并非所有物件都可以(或應該)設定任意屬性。例如,如果一個NoneType物件可以設定屬性是沒有意義的,就像object()一個None物件也沒有__dict__屬性一樣。實際上,兩者的唯一區別是None物件具有__bool__屬性。例如:
n = None
o = object()
type(n)
>>> <class 'NoneType'>
set(dir(n)) - set(dir(o))
>>> {'__bool__'}
isinstance(n, object)
>>> True
bool(n)
>>> False
繼承自是object自動的,并且就像任何其他繼承方式一樣,可以向子項添加自己的類方法和屬性。__dict__正如您已經展示的那樣,Python 會自動為自定義資料型別添加屬性。
簡而言之,__dict__對于沒有自定義可寫屬性的物件(即NoneType),添加物件的屬性比將其洗掉要容易得多。
根據評論更新:
原評論:
那么假設它
__setattr__檢查是否存在__dict__并相應地引發例外是否安全?– bool3max
在 CPython 中,背后的邏輯object.__setattr__(self, name, value)是由 Objects/object.c 實作的_PyObject_GenericSetAttrWithDict(參見CPython 源代碼)。具體來說,如果name引數是一個字串,那么它會檢查__dict__物件的一個??插槽中的物件并確保它“準備好”(請參閱此行)。
物件的就緒狀態由 確定PyType_Ready(),簡要描述并參考自此處:
在 C 中定義 Python 型別涉及使用您關心的值填充 PyTypeObject 結構的欄位。我們將這些欄位中的每一個稱為“插槽”。
在定義準備好后,我們將其傳遞給 PyType_Ready() 函式,該函式執行許多操作,包括將大部分型別定義暴露給 Python 的屬性查找機制。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/384561.html
