【问题标题】:TypeError during assignment to attribute reference?分配给属性引用期间的TypeError?
【发布时间】:2016-09-21 19:21:59
【问题描述】:

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

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

我想知道如何获得这个TypeError

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

【问题讨论】:

  • 我用python大概2年了,从来没有遇到过这种情况。

标签: python python-3.x typeerror attr


【解决方案1】:

这个文档行真的已经过时了。它至少可以追溯到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 编写的类型的属性。仍然采用此代码路径,但它不像文档描述的那样通用:

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

【讨论】:

  • 你提示我一个答案object.some_attr 引发 TypeError :)
  • 我认为如果您明确删除__setattr__,这种情况仍然会发生。不过我没有测试它。
  • @Kritzefitz 不,不,你不能del,如果你不能分配!
  • 我稍微修改了我的问题,因为您确实向我透露了我的问题。
【解决方案2】:

这段代码产生了一个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 而言,也许这部分文档只是一个遗物。

【讨论】:

  • 在我的情况下,f.func_globals 不会引发错误。我使用 Python 3.5.2。
【解决方案3】:

如果你想在代码中引发 TypeError:

raise TypeError

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

【讨论】:

    猜你喜欢
    • 2017-03-08
    • 2019-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多