python - 如何保护内置类型不被覆盖(分配给)它们的方法?
问题描述
我注意到
int.__str__ = lambda x: pass
产生错误。
我明白了,为什么这是被禁止的。但是怎么做?我可以在“正常”代码中使用它吗?
解决方案
对于直接在int
自身和其他内置类型(而不是它们的实例)上设置属性,这种保护发生在 中type.__setattr__
,它明确禁止在内置类型上设置属性:
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 实现它们。你可以假装这样做,通过编写一个带有 custom 的元类__setattr__
,但这使得使用其他有用的元类更加复杂,而且它仍然没有防止有人type.__setattr__
直接呼叫您的课程。(尝试类似的技巧object.__setattr__(int, ...)
不起作用,因为有一个特定的检查来捕捉它。)
您没有询问内置类型的实例,但它们也很有趣。大多数内置类型的实例不能在它们上设置属性,因为没有地方可以放置这些属性 - 没有__dict__
。它们通常不是具有特殊的“不允许设置”__setattr__
或缺少 a ,而是继承自,后者知道如何处理没有 no 的对象:__setattr__
__setattr__
object
__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;
}
...
推荐阅读
- flutter - Listview builder 没有获取完整的 List Map 数据 Flutter
- java - 使用 PDFBOX 合并 PDF 仅在 AWS lambda 上给出 65536 错误的临时文件大小
- flutter - 我怎么能把一些按钮放在屏幕底部但是呢?
- julia - JLD2:使用函数保存/加载结构
- aws-lambda - 如何在无服务器框架应用程序中实现两个独立的服务?
- javascript - 将参数转发给纯函数的综合和简单方法?
- java - 模拟器:进程完成,退出代码 -1073741511 (0xC0000139) Andrioid Studio
- javascript - 无法在 Typescript 中的函数内调用函数
- flutter - Flutter 事件在流中丢失
- javascript - 根据 div 行数减小字体大小