如何判断Python中的序列是否可变?

时间:2017-04-24 07:40:24

标签: python

对于内置Python类型,list是可变的,但tuple不是。对于其他序列,有没有办法判断它们是否可变?像可变序列一样,通常有.pop().insert().extend()成员函数?所有可变序列和不可变序列是否都从单独的内置类型继承,然后可以用来区分它们?

4 个答案:

答案 0 :(得分:17)

您可以检查该类型是否是collections.abc.MutableSequence抽象基类的子类(或Python 2中的collections.MutableSequence):

>>> issubclass(list, MutableSequence)
True
>>> issubclass(tuple, MutableSequence)
False

>>> isinstance([], MutableSequence)
True
>>> isinstance((), MutableSequence)
False

请注意,与某些ABCs(例如,CollectionIterable(提供issubclass / isinstance的挂钩)不同,此要求其子类为显式注册,因此这可能不适用于所有序列类型的开箱即用。

但是,只要实现了所需的抽象方法,就可以使用MutableSequence.register(MyType)手动将类型注册为子类。

答案 1 :(得分:2)

在没有理解你想要实现的目标之前,没有简单的解决方案,所以我们需要了解可变性是什么?

让我们简单地将 mutable type 定义为我们可以在某个位置设置项目的实例的类型(通过字典中的键,按列表中的索引),i。即他们实施__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

答案 2 :(得分:0)

如果您的序列名为seq,那么测试不变性的“duck typing”方法是尝试为seq[0]分配一个值,如果它不起作用则捕获该异常。 。

答案 3 :(得分:-5)

如果对象仅包含不可变类型的子对象,则该对象是不可变的。 如果类型是内置的不可变类型,则类型是不可变的:str,int,bool,float,tuple。