Что в Python означает, является ли объект подписываемым или нет?

Какие типы объектов попадают в область "подписки"?

7 ответов

Решение

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

Вдобавок к моей голове, следующие единственные встроенные модули, которые могут быть подписаны:

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

Но ответ Мипади является правильным - любой класс, который реализует __getitem__ подписывается

Значение индекса в вычислениях: "символ (условно записанный как индекс, но на практике обычно нет), используемый в программе, один или с другими, для указания одного из элементов массива".

Теперь в простом примере, представленном user2194711, мы видим, что добавляемый элемент не может быть частью списка по двум причинам:

1) Мы не вызываем метод append; потому что это нужно () называть это.

2) ошибка указывает на то, что функция или метод не могут быть подписаны; означает, что они не индексируются как список или последовательность.

Теперь посмотри:

>>> var = "myString"
>>> def foo(): return 0
... 
>>> var[3]
't'
>>> foo[3]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'function' object is not subscriptable

Это означает, что нет подписок или сказать элементы в function как они встречаются в последовательности; и мы не можем получить к ним доступ, как мы, с помощью [],

Также; как сказал Мипади в своем ответе; Это в основном означает, что объект реализует __getitem__() метод. (если это по подписке). Таким образом, ошибка выдает:

arr.append["HI"]

TypeError: объект builtin_function_or_method не может быть подписан

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

Например, см.: Application Scripting Framework

Теперь, если Алистер не знал, о чем он спрашивал, и действительно имел в виду "подписываемые" объекты (отредактированные другими), то (как ответил и Мипади) это будет правильным:

Подписываемый объект - это любой объект, который реализует __getitem__ особый метод (мыслительные списки, словари).

У меня была такая же проблема. я делал

arr = []
arr.append["HI"]

Итак, используя [ был причиной ошибки. Так должно быть arr.append("HI")

Как следствие предыдущих ответов здесь, очень часто это признак того, что вы думаете, что у вас есть список (или 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) поймать его тоже.)

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

Другие вопросы по тегам