用户定义的类是否可变
说我想创建一个类car
,tractor
和boat
。所有这些类都有一个实例,engine
我想在一个列表中跟踪所有引擎。如果我正确理解电机对象是否可变,我可以将其存储为属性,car
也可以将其存储在列表中。
我无法找到有关用户定义的类是否可变以及在定义它们时是否可以选择的任何可靠信息,有人能说清楚吗?
-
用户类被认为是可变的。Python没有(绝对)私有属性,因此您始终可以通过接触内部来更改类。
为了将您的类用作a中的键
dict
或将它们存储在中set
,您可以定义一个.__hash__()
方法和一个.__eq__()
方法,从而保证您的类是不可变的。在这种情况下,通常将类API设计为在创建后不改变内部状态。例如,如果您的引擎由其ID唯一定义,则可以将其用作哈希的基础:
class Engine(object): def __init__(self, id): self.id = id def __hash__(self): return hash(self.id) def __eq__(self, other): if isinstance(other, self.__class__): return self.id == other.id return NotImplemented
现在,您可以在集合中使用Engine类的实例:
>>> eng1 = Engine(1) >>> eng2 = Engine(2) >>> eng1 == eng2 False >>> eng1 == eng1 True >>> eng1 == Engine(1) True >>> engines = set([eng1, eng2]) >>> engines set([<__main__.Engine object at 0x105ebef10>, <__main__.Engine object at 0x105ebef90>]) >>> engines.add(Engine(1)) >>> engines set([<__main__.Engine object at 0x105ebef10>, <__main__.Engine object at 0x105ebef90>])
在上面的示例中,我
Engine(1)
向集合添加了另一个实例,但是该实例已被识别为已经存在,并且集合没有更改。请注意,就列表而言,
.__eq__()
实现是重要的。列表并不关心对象是否可变,但是使用.__eq__()
适当的方法,您可以测试给定引擎是否已在列表中:>>> Engine(1) in [eng1, eng2] True