如何防止内建型别覆写(指派)其方法?

2024-04-25 22:29:53 发布

您现在位置:Python中文网/ 问答频道 /正文

我注意到

int.__str__ = lambda x: pass

产生一个错误。你知道吗

我明白了,为什么这是禁止的。但是怎么做呢?我能用“普通”代码吗?你知道吗


Tags: lambda代码错误passintstr
1条回答
网友
1楼 · 发布于 2024-04-25 22:29:53

对于直接在int本身和其他内置类型(而不是它们的实例)上设置属性,这种保护发生在^{},它特别禁止在内置类型上设置属性:

static int
type_setattro(PyTypeObject *type, PyObject *name, PyObject *value)
{
    int res;
    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;
    }
    ...

Py_TPFLAGS_HEAPTYPE是一个标志,指示是否在Python而不是C中定义了类型


除非用C实现自己的类,否则不能对自己的类做同样的事情。可以假装这样做,用自定义的__setattr__编写一个元类,但这会使使用其他有用的元类变得更加复杂,而且仍然不能阻止有人直接调用你的类type.__setattr__。(用object.__setattr__(int, ...)尝试一个类似的技巧是行不通的,因为有一个specific check来捕捉它。)


您没有询问内置类型的实例,但它们也很有趣。大多数内置类型的实例不能在其上设置属性,因为没有地方放置这些属性-没有__dict__。它们通常从object继承__setattr__,而不是有一个特殊的“不允许设置”__setattr__,或者缺少__setattr__,这些knows how to handle对象没有__dict__

descr = _PyType_Lookup(tp, name);

if (descr != NULL) {
    Py_INCREF(descr);
    f = descr->ob_type->tp_descr_set;
    if (f != NULL) {
        res = f(descr, obj, value);
        goto done;
    }
}

if (dict == NULL) {
    dictptr = _PyObject_GetDictPtr(obj);
    if (dictptr == NULL) {
        if (descr == NULL) {
            PyErr_Format(PyExc_AttributeError,
                         "'%.100s' object has no attribute '%U'",
                         tp->tp_name, name);
        }
        else {
            PyErr_Format(PyExc_AttributeError,
                         "'%.50s' object attribute '%U' is read-only",
                         tp->tp_name, name);
        }
        goto done;
    }
    ...

相关问题 更多 >

    热门问题