2016-09-21 128 views
1

讀取在Python的文檔約Assignment statements我發現這一點:分配給屬性引用時的TypeError?

如果目標是一個屬性引用:引用中的主表達式。它應該產生具有可分配屬性的對象;如果情況並非如此,則引發TypeError。然後要求該對象將指定的對象分配給給定的屬性;如果它不能執行任務,則會引發異常(通常不一定是AttributeError)。

我在想如何得到這個TypeError

什麼樣的Python類型沒有常規設置屬性?

+0

我使用python大約2年,但從未遇到這樣的情況。 – godaygo

回答

4

此文檔行只是過時了。它至少可以追溯到Python 1.4,早在類型/階級統一之前。我相信那時,試圖做這樣

x = 1 
x.foo = 3 

東西將產生一個類型錯誤,但我並沒有編寫Python當時,我沒有足夠古老的解釋版本進行測試。

如果你看一下source code的屬性分配調度,你可以看到記錄的檢查仍然存在:

if (tp->tp_setattro != NULL) { 
    ... 
    return ...; 
} 
if (tp->tp_setattr != NULL) { 
    ... 
    return ...; 
} 
Py_DECREF(name); 
assert(name->ob_refcnt >= 1); 
if (tp->tp_getattr == NULL && tp->tp_getattro == NULL) 
    PyErr_Format(PyExc_TypeError, 
       "'%.100s' object has no attributes " 
       "(%s .%U)", 
       tp->tp_name, 
       value==NULL ? "del" : "assign to", 
       name); 
else 
    PyErr_Format(PyExc_TypeError, 
       "'%.100s' object has only read-only attributes " 
       "(%s .%U)", 
       tp->tp_name, 
       value==NULL ? "del" : "assign to", 
       name); 
return -1; 

如果對象的類型對設置屬性沒有套路,Python會引發一個錯誤,抱怨「無屬性」或「只讀屬性」取決於類型是否具有獲取屬性的例程。我相信在早期,像int這樣的類型將會沿着這條代碼路徑走下去。但是,所有類型現在都繼承了object這樣的例程,所以我不認爲這個代碼路徑是被採用的。

有一個在type.__setattr__這就提出了設置在C語言編寫的類型本代碼路徑依舊採取屬性的TypeError相關的代碼路徑,但它並不像一般什麼文檔描述:

if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) { 
    PyErr_Format(
     PyExc_TypeError, 
     "can't set attributes of built-in/extension type '%s'", 
     type->tp_name); 
    return -1; 
} 
+0

你提示我一個回答'object.some_attr'引發TypeError :) – godaygo

+0

我認爲如果你明確地刪除了'__setattr__',仍然會發生。我沒有測試它。 – Kritzefitz

+0

@Kritzefitz不,不,你不能'刪除',如果你不能指定! – godaygo

0

這代碼產生TypeError而且好像它是什麼文件描述:

>>> def f(): pass 
... 
>>> f.func_globals = 0 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: readonly attribute 

但是,這是真的TypeError提出,因爲文件說?我真誠地懷疑它。我猜func_globals實現只是提高TypeError如果你嘗試給它分配一些東西。

BTW ...

我實際上excpect在接下來的例子中是相同的,但它是一個AttributeError代替:

>>> class A(object): 
...  __slots__ = 'a', 
... 
>>> A().b = 0 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: 'A' object has no attribute 'b' 

更新(Python 3中)

上面是在Python 2.7。在Python 3中,沒有func_globals,所以這不適用(你可以指定任何東西)。

Python 3中的函數具有什麼屬性,當它是隻讀時,似乎會引發AttributeError

>>> f.__globals__ = 0 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: readonly attribute 

這對我來說非常有意義。就Python 3而言,這部分文檔可能只是一個遺留問題。

+0

它不會在'f.func_globals'中引發錯誤。我使用Python 3.5.2。 – godaygo

+0

@godaygo你是對的,我用Python 2.7 ... – zvone

相關問題