Что означает то, если объект Python “subscriptable” или нет?

324
задан Danijel 16 September 2019 в 02:26
поделиться

4 ответа

Это в основном означает, что объект реализует __getitem__() метод. Другими словами, это описывает объекты, которые являются "контейнерами", означая, что они содержат другие объекты. Это включает списки, кортежи и словари.

298
ответ дан tzot 23 November 2019 в 00:53
поделиться

Первое, что пришло на ум, следующее единственное, созданное-ins, которые subscriptable:

string:  "foobar"[3] == "b"
tuple:   (1,2,3,4)[3] == 4
list:    [1,2,3,4][3] == 4
dict:    {"a":1, "b":2, "c":3}["c"] == 3

, Но ответ mipadi корректен - любой класс, который реализует __getitem__, subscriptable

70
ответ дан Filipp W. 23 November 2019 в 00:53
поделиться

scriptable объект является объектом, который записывает операции, сделанные к нему, и он может сохранить их как "сценарий", который может быть воспроизведен.

, Например, см.: Приложение, Пишущее сценарий Платформы

Теперь, если Alistair не знал то, что он спросил и действительно имел в виду "subscriptable" объекты (как отредактировано другими), тогда (как mipadi также, ответило), это - корректное:

А subscriptable объект является любым объектом, который реализует __getitem__ специальный метод (думайте списки, словари).

15
ответ дан tzot 23 November 2019 в 00:53
поделиться

Как следствие предыдущих ответов здесь, очень часто это признак того, что вы думаете, что у вас есть список (или dict, или другой подписываемый объект), когда у вас его нет.

Например, допустим, у вас есть функция, которая должна вернуть список;

def gimme_things():
    if something_happens():
        return ['all', 'the', 'things']

Теперь, когда вы вызываете эту функцию, и something_happens() по какой-то причине не возвращает True значение, что происходит? if терпит неудачу, и поэтому вы проваливаетесь; gimme_things ничего явно не return - так что фактически, это будет неявно return None. Тогда этот код:

things = gimme_things()
print("My first thing is {0}".format(things[0]))

потерпит неудачу с «объект NoneType не может быть подписан», потому что, ну, things равен None, и поэтому вы пытаетесь сделать None[0], который не имеет смысл, потому что ... что говорится в сообщении об ошибке.

Есть два способа исправить эту ошибку в вашем коде - первый - избежать ошибки, проверив, что things действительно допустим, прежде чем пытаться его использовать;

things = gimme_things()
if things:
    print("My first thing is {0}".format(things[0]))
else:
    print("No things")  # or raise an error, or do nothing, or ...

или эквивалентно перехватите исключение TypeError;

things = gimme_things()
try:
    print("My first thing is {0}".format(things[0]))
except TypeError:
    print("No things")  # or raise an error, or do nothing, or ...

Другой способ - изменить дизайн gimme_things, чтобы убедиться, что он всегда возвращает список. В данном случае это, вероятно, более простой дизайн, потому что это означает, что если во многих местах есть похожая ошибка, они могут быть простыми и идиоматичными.

def gimme_things():
    if something_happens():
        return ['all', 'the', 'things']
    else:  # make sure we always return a list, no matter what!
        logging.info("Something didn't happen; return empty list")
        return []

Конечно, то, что вы поместите в ветку else:, зависит от вашего варианта использования. Возможно, вам следует вызвать исключение при сбое something_happens(), чтобы сделать его более очевидным и явным, если что-то действительно пошло не так? Добавление исключений в ваш собственный код - это важный способ дать себе точное представление о том, что происходит, когда что-то выходит из строя!

(Обратите внимание также, что это последнее исправление еще не полностью исправляет ошибку - оно не позволяет вам пытаться индекс None, но things[0] все еще является IndexError, когда things - пустой список. Если у вас есть try, вы можете сделать except (TypeError, IndexError), чтобы перехватить его тоже.)

2
ответ дан 23 November 2019 в 00:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: