我需要动态地向 python 对象添加一个属性(包含一个元组或对象)。这适用于我编写的 Python 类,但不适用于内置类。
考虑以下程序:
import numpy as np
class My_Class():
pass
my_obj = My_Class()
my_obj2 = My_Class()
my_obj.__my_hidden_field = (1,1)
my_obj2.__my_hidden_field = (2,1)
print(my_obj.__my_hidden_field, my_obj2.__my_hidden_field)
这会正确打印 (1, 1) (2, 1)。但是,以下程序不起作用。
X = np.random.random(size=(2,3))
X.__my_hidden_field = (3,1)
setattr(X, '__my_hidden_field', (3,1))
以上两行都会抛出以下错误 # AttributeError: 'numpy.ndarray' object has no attribute '__my_hidden_field'
现在,从这些问题(即 Attribute assignment to built-in object 、 Can't set attributes of object class 、 python: dynamically adding attributes to a built-in class )中找到的原因是 Python 不允许动态添加属性到 built_in 对象。
答案摘录:https://stackoverflow.com/a/22103924/8413477
This is prohibited intentionally to prevent accidental fatal changes to built-in types (fatal to parts of the code that you never though of). Also, it is done to prevent the changes to affect different interpreters residing in the address space, since built-in types (unlike user-defined classes) are shared between all such interpreters.
但是,所有的答案都非常陈旧,我非常需要为我的研究项目做这件事。
虽然有一个模块允许向内置类添加方法: https://pypi.org/project/forbiddenfruit/
但是,它不允许为每个对象添加对象/属性。
有什么帮助吗?
请您参考如下方法:
你可能想要 weakref.WeakKeyDictionary .从文档中,
This can be used to associate additional data with an object owned by other parts of an application without adding attributes to those objects.
像一个属性,而不像一个普通的字典,这允许对象在没有其他引用时被垃圾收集。
你会用
查找字段my_hidden_field[X]
代替
X._my_hidden_field
两个注意事项:首先,由于弱键可能会在没有警告的情况下随时被删除,因此您不应遍历 WeakKeyDictionary。不过,查找您引用的对象很好。其次,您不能对用 C 编写的没有插槽的对象类型进行弱引用(对于许多内置函数来说都是如此),或者用 Python 编写的不允许 __weakref__< 的类型 属性(通常是由于 __slots__)。
如果这是个问题,您可以只对这些类型使用普通字典,但您必须自己清理它。
