是否保证__dict__的键是字符串值(实现自定义__deepcopy__)

时间:2014-03-09 21:36:33

标签: python

我在数据模型层次结构的基类中实现__deepcopy__()方法。通过对原始copy.deepcopy()的值调用__dict__并将它们分配给适当的键来复制原始对象的属性。在传统的用法下(也就是说,没有人去过并直接将复杂对象直接添加到原始对象的__dict__属性中),这些关键值是否总是字符串,因此不需要深入 - 复制了吗?

例如,在以下代码中:

 def __deepcopy__(self, memo=None):
    if memo is None:
        memo = {}
    try:
        o = memo[id(self)]
    except KeyError:
        o = type(self).__new__(self.__class__)
        memo[id(self)] = o
    for k in self.__dict__:
        # o.__dict__[copy.deepcopy(k, memo)] = copy.deepcopy(self.__dict__[k], memo)
        o.__dict__[k] = copy.deepcopy(self.__dict__[k], memo)
    return o

当前行:

o.__dict__[k] = copy.deepcopy(self.__dict__[k], memo)

假设__dict__符号表中的键是简单字符串(或不需要特殊处理的其他类型的对象)。

我应该使用:

o.__dict__[copy.deepcopy(k, memo)] = copy.deepcopy(self.__dict__[k], memo)

相反,它允许符号表中的键本身更复杂或更丰富的对象?

2 个答案:

答案 0 :(得分:2)

我相信答案是肯定的。课程The documentation表示:

  

类具有由字典对象实现的命名空间。类属性引用被转换为此字典中的查找,例如,C.x已转换为C.__dict__["x"]

这似乎表明,如果你只使用普通的属性赋值,你将总是得到字符串键。 (下面关于实例的部分不是那么明确,但也指的是一个“属性字典”,它显然意味着与类相同。)

当然,正如你在问题中提到的那样,人们可以做一些奇怪的事情,但如果你假设除了正常__dict__之外没有任何东西被添加到obj.attr = value,那么你应该没事。

答案 1 :(得分:1)

虽然可以将非字符串键添加到对象的__dict__(见下文),但毫无疑问,更简单的代码版本可以正常工作。我从来没有遇到任何人在对象的__dict__中使用非字符串键。

如果有人做了一些违反这个假设并且让你的代码破坏的奇怪事情,那就是他们的错。我声称你的代码仍然是正确和有效的,尽管在这些奇怪的情况下打破了。

这是一种可以将非字符串键添加到对象的dict的方法:

obj.__dict__.update({ object(): 666 })
obj.__dict__
=> {<object at 0x1002b1450>: 666}
相关问题