关于可清洗对象的说明需要说明

Auf*_*ind 9 python hash

Mark RansomSO中回答了关于哈希SO问题:

[...]如果对象具有在其生命周期内永远不会更改的哈希值,则该对象是可清除的.因此,根据官方定义,即使它具有__hash__()功能,任何可变的东西都不能被清除.我关于这两个要求的说法是不真实的,因为可清除已经暗示要求是不可变的.

我想确保,我做对了 - 即使是非母语人士 - 所以我希望有人在我弄错的时候纠正我.

假设这门课

class Author(object):
    def __init__(self, id, name, age):
        self.id = id
        self.name = name
        self.age = age

    def __eq__(self, other):
        return self.id==other.id\
               and self.name==other.name

    def __hash__(self):
        return hash(('id', self.id,
                     'name', self.name))
Run Code Online (Sandbox Code Playgroud)

我明白了,这__eq__允许我将这个类的对象与==运算符进行比较.从马克斯回答我理解,即使我的对象peter = Author(1, "Peter", 33)有一个__hash__它是不可清洗的,因为我可能做的事情peter.age = 43,这意味着它不是不可变的.所以我的类的对象Author是不可编辑的,因此不能用作例如dictionarys中的键?我是否做得对或看起来是否需要更多解释?:-)

Fre*_*Foo 11

如果您承诺永远不会重置idname使用它们,则此类的实例是可清除的.您无法保证这些属性永远不会被重置,因为Python原则"我们都同意成年人",但提供重置__hash__依赖属性的方法将是非常糟糕的风格.

例如,如果你set_name在实例上提供了一个方法Author,但是没有set_id,那么该类的客户可以合理地假设在该实例上__hash__运行.id

如果您想向客户明确Author说明他们不应该重置某些属性,您可以通过_在其名称前添加一个属性来将其标记为私有.如果您仍然希望使用其通用名称提供(只读)对该属性的访问,则可以将其设为属性:

class Author(object):
    def __init__(self, id, name, age):
        self._id = id
        self._name = name
        self.age = age      # ages tend to change, so mutable

    id = property(lambda self: self._id)
    name = property(lambda self: self._name)

    def __eq__(self, other):
        return self.id==other.id\
               and self.name==other.name

    def __hash__(self):
        return hash(('id', self.id,
                     'name', self.name))
Run Code Online (Sandbox Code Playgroud)