类型的__dict__
是只读的dictproxy
对象。我想知道它的目的是什么。是否只允许修改内置类型"?我发现了一种可以绕过它的方法。我知道修改内置类型并不是一个好主意。但我试图在飞行中修改Cython的cdef class
。
我想知道以这种方式修改__dict__
的{{1}}是否有危险?
以下是代码:
cdef class
答案 0 :(得分:13)
dictproxy
(在类中找到)的目的是允许Python解释器中的优化并确保其稳定性。有关优化要求的详细信息,请参阅下面的MartijnPieters评论,这显然依赖于class.__dict__
始终为字符串的键。
dictproxy
似乎也起到了防止翻译中某些不稳定性的作用。有关这种不稳定性的更多信息,请参阅python.org上讨论的错误报告和错误修复,标题为Bypassing __dict__ readonlyness。如果您不使用某种代理机制,则可以写入__dict__
。如果可以写入,则可以删除。在错误报告中,他们讨论了可能删除__dict__
并导致解释程序崩溃的一些情况。
请注意,这与您 可以 直接分配给__setitem__()
或<{1}}的类实例形成对比:
instance.__dict__['x'] = 1
此外,可以删除实例__dict__
。如果将其删除,则在尝试进行属性分配时会自动重新创建:
del instance.__dict__
instance.a = 1
instance.__dict__
总而言之,dictproxy
允许类更优化地运行并使解释器更稳定。
答案 1 :(得分:5)
__dict__
是一个包含类属性的命名空间对象。
只要您不修改__dict__
本身,就不会有修改dict对象的问题:
示例:
//good
MyClass.x = 1
//bad
MyClass.__dict__['x'] = 1
//good
m = MyClass()
m.x = 1
//also good
m.__dict__['x'] = 1
Python文档[LINK]:
Attribute assignment updates the module’s namespace dictionary, e.g., m.x = 1 is equivalent to m.__dict__["x"] = 1.
因此修改 dict 的对象应该没有问题。
<强>此外:强>
因为我们可以修改类的属性,所以类的dict总是可写的:
__dict__ | The namespace supporting arbitrary function attributes. | Writable
注意强>
可能是Cpython的实现比pyhton略有不同,但我可以从文档中读到它未提及的内容。