在Python的文档中阅读Assignment statements我发现了这个:
如果目标是属性引用:将评估引用中的主表达式。它应该产生一个具有可分配属性的对象;如果不是这种情况,则会引发
TypeError
。然后要求该对象将指定的对象分配给给定的属性;如果它无法执行赋值,则会引发异常(通常但不一定是AttributeError
)。
我想知道如何获得此TypeError
?
Python的类型没有设置属性的例程?
答案 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