Подтвердить что ты не робот

Как определить, является ли последовательность в Python изменчивой или нет?

Для встроенных типов Python list изменен, но tuple нет. Для других последовательностей есть ли способ определить, являются ли они изменяемыми или нет? Как измененная последовательность обычно имеет .pop(), .insert() или .extend() функцию-член? Все ли изменяемые последовательности и неизменяемые последовательности наследуются от отдельных встроенных типов, которые затем могут использоваться для их дифференциации?

4b9b3361

Ответ 1

Вы можете проверить, является ли этот тип подклассом базового класса collections.abc.MutableSequence (или collections.MutableSequence в Python 2):

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

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

Обратите внимание, что в отличие от некоторых ABC (например, Collection и Iterable), которые предоставляют крючки для issubclass/isinstance) это требует, чтобы его подклассы были явно зарегистрированы, поэтому это может не работать из коробки со всеми типами последовательностей.

Однако вы можете вручную зарегистрировать тип в качестве подкласса, используя MutableSequence.register(MyType), если будут реализованы требуемые абстрактные методы.

Ответ 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

Ответ 3

Если ваша последовательность называется seq, метод "утиной печати" для проверки неизменяемости будет состоять в том, чтобы попытаться присвоить значение seq[0] и поймать исключение, если оно не работает...

Ответ 4

Объект неизменен, если он содержит только неизменяемые типы как под-объекты. Тип является неизменным, если он является встроенным неизменяемым типом: str, int, bool, float, tuple.