我目前正在用Python处理一些数据结构,我希望它们是可散列的(这样它们就可以存储在字典和集合中)。到目前为止,我已经看到了三种主要的方法:
①构造一个普通类并给它一个__hash__
方法。你知道吗
class DataStructure:
def __init__(self, member):
self.member = member
def __hash__(self):
return hash(self.member)
def __eq__(self, other):
return isinstance(other, DataStructure) and self.member == other.member
但这只是“相信”最终用户永远不会变异member
。如果他们在把它存储在集合或字典中的时候对它进行了变异,就会产生不好的结果。你知道吗
②使用collections.namedtuple
。你知道吗
DataStructure = collections.namedtuple('DataStructure', ('member',))
但是namedtuple
不能有成员函数,如果有成员函数就更好了。你知道吗
③使用__slots__
并重写__setattr__
,如here所示。你知道吗
class DataStructure:
__slots__ = ['member']
def __init__(self, member):
super(DataStructure, self).__setattr__('member', member)
def __setattr__(self, key, value):
raise ValueError('Mutating this object is Not Allowed')
# also define __hash__ and __eq__ here
但是这个doesn't seem to be intended usage,也使得继承更加复杂。最重要的是,它不觉得“Python”。你知道吗
那么:在Python中创建不可变类的首选方法是什么?希望自定义数据结构是可散列的似乎并不奇怪,毕竟这就是__hash__
存在的原因。我更愿意让类变为不可变的,而不是告诉用户“您可以自由地分配给这些成员,但是如果这样做,您的集合和字典可能会崩溃和烧毁”——Python通常会首先尝试不让人们犯这些错误(这就是set
和frozenset
是不同的原因)。你知道吗
在要“只读”的变量前面加一个“\”。它仍然可以从类内更改,但是IDE不会预测它,如果您尝试从类外更改它们,它会抛出警告。你知道吗
绝对的不可变性可能无法实现,但您可以使用properties来明确您的意图:
这样
member
作为“public”属性公开,但不可写:一个坚定的最终用户仍然可以变异
self._member
,但是在这一点上,你会期望他们知道他们做了错误的事情。你知道吗相关问题 更多 >
编程相关推荐