2016-09-21 89 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

相关问题