jon*_*opf 23 python class mutable immutability
说我想创建一个类car,tractor和boat.所有这些类都有一个实例,engine我想跟踪单个列表中的所有引擎.如果我正确理解电机对象是否可变,我可以将其存储为列表中的属性car以及相同的实例.
我无法找到关于用户定义的类是否可变的任何可靠信息,以及在定义它们时是否有选择可以选择,是否有人可以解释一下?
Mar*_*ers 33
用户类被认为是可变的.Python没有(绝对)私有属性,所以你总是可以通过进入内部来改变一个类.
要将您的类用作a中的键 dict或将它们存储在a中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
Run Code Online (Sandbox Code Playgroud)
现在,您可以在集合中使用类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>])
Run Code Online (Sandbox Code Playgroud)
在上面的示例中,我将另一个Engine(1)实例添加到集合中,但它被识别为已存在且集合未更改.
请注意,就列表而言,.__eq__()实施是重要的; 名单不关心,如果对象是可变的或没有,但随着.__eq__()替代方法,你可以测试一个给定的发动机已经在一个列表:
>>> Engine(1) in [eng1, eng2]
True
Run Code Online (Sandbox Code Playgroud)