在分配到属性引用期间是否为TypeError?

时间:2016-09-21 19:21:59

标签: python python-3.x typeerror attr

在Python的文档中阅读Assignment statements我发现了这个:

  

如果目标是属性引用:将评估引用中的主表达式。它应该产生一个具有可分配属性的对象;如果不是这种情况,则会引发TypeError。然后要求该对象将指定的对象分配给给定的属性;如果它无法执行赋值,则会引发异常(通常但不一定是AttributeError)。

我想知道如何获得此TypeError

Python的类型没有设置属性的例程?

3 个答案:

答案 0 :(得分:4)

此文档行真的过时了。在类型/类统一之前很久,它至少可以追溯到Python 1.4。我当时相信,尝试做类似

的事情
x = 1
x.foo = 3

会产生一个TypeError,但当时我还没有编写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__中有一个相关的代码路径,它引发TypeError来设置用C编写的类型的属性。这个代码路径仍然被采用,但它不像文档描述的那样通用:< / p>

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;
}

答案 1 :(得分: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

<强>顺便说一句...

我实际上会在下一个示例中对此进行同样的检查,但它是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而言,这部分文档可能只是一个遗留物。

答案 2 :(得分:-2)

如果要在代码中引发TypeError:

raise TypeError

我建议您阅读Python中的异常和异常处理以获取更多信息。 https://docs.python.org/3/tutorial/errors.html