对于Python内置类型,list
是可变的,但是tuple
不可变。对于其他序列,有没有办法判断它们是否可变?就像可变序列通常具有.pop()
、.insert()
或.extend()
成员函数一样?所有可变序列和不可变序列是否都继承自单独的内置类型,然后可以用来区分它们?
对于Python内置类型,list
是可变的,但是tuple
不可变。对于其他序列,有没有办法判断它们是否可变?就像可变序列通常具有.pop()
、.insert()
或.extend()
成员函数一样?所有可变序列和不可变序列是否都继承自单独的内置类型,然后可以用来区分它们?
collections.abc.MutableSequence
抽象基类的子类(或Python 2中的collections.MutableSequence
):>>> issubclass(list, MutableSequence)
True
>>> issubclass(tuple, MutableSequence)
False
>>> isinstance([], MutableSequence)
True
>>> isinstance((), MutableSequence)
False
issubclass
/isinstance
挂钩的Collection
和Iterable
)不同,这个类要求其子类必须显式注册,因此对于所有类似序列的类型,这可能无法直接使用。MutableSequence.register(MyType)
手动将类型注册为子类。Iterable
,它实际上只是一个接口,规定子类定义了 __iter__
。但对于定义了混合方法的 ABC(如 MutableSequence
),强制将其添加到其他类中而没有选择退出将是危险的。我想这就是为什么它必须是明确的设计决策的原因。 - Will Vousdenisinstance
进行检查是与此一致的,因此如果没有受到第三方或遗留代码的限制,我会选择该方法。 - spectras在不了解您试图实现什么之前,就没有简单的解决方案,因此我们需要了解可变性是什么?
让我们简单地定义可变类型为这种类型的实例,我们可以在某个位置设置项(在字典中按键,在列表中按索引),即它们实现__setitem__
方法。
在Python
中检查某些内容的最常用方法是请求宽恕而非允许,因此像这样做会有所帮助:
def is_mutable(cls):
try:
cls.__setitem__
except AttributeError:
return False
else:
return True
但它也可以被替换为
def is_mutable(cls):
return hasattr(cls, '__setitem__')
两者的工作方式相似,取决于你的喜好。
示例
types = [tuple, str, list, dict]
for type_ in types:
print(type_.__name__, 'is mutable:', is_mutable(type_))
tuple is mutable: False
str is mutable: False
list is mutable: True
dict is mutable: True
set
没有__setitem__
但它是可变的。另一方面,set
也不是序列类型,但dict
也不是。 - tobias_kset
绝对是可变的,但它不是“可变序列”——dict
也不是,因此 __setitem__
的存在可能不是最好的指标。此外,还有其他可变序列,例如(严格的)栈和队列,它们不允许随机访问。 - tobias_ktuple
/ list
/ str
,发帖者应该决定是否认为dict
是可变的。 - Azat Ibrakovset
添加支持,我们可能还想检查标准库中的所有类型,但仍然无法完美地处理所有类型。 - Azat Ibrakovseq
,测试不可变性的“鸭子类型”方式是尝试给seq[0]
赋值,并在它不起作用时捕获异常...
del seq[0]
和 seq.insert
。 - donkopotamusseq[0] = seq[0]
避免修改序列,但这仍然无法解决空或字典边缘情况。 - Jonas Schäfer如果一个对象只包含不可变类型的子对象,则该对象是不可变的。 如果一个类型是内置的不可变类型:str、int、bool、float、tuple,则它是不可变的。
list
仍然是可变的 --- 您可以用其他值替换其中任何不可变值。(您也可以添加或删除值。) - Kevin J. Chase
isinstance(thing, MutableSequence)
,来自ABCs:https://docs.python.org/3/library/collections.abc.html#collections.abc.MutableSequence - jonrsharpetry: sequence.do_something() except: #don't do anything
. - Aran-Fey