Що це означає, якщо об’єкт Python "піддається підключенню" чи ні?


Відповіді:


356

Це в основному означає, що об'єкт реалізує __getitem__()метод. Іншими словами, він описує об'єкти, які є "контейнерами", тобто вони містять інші об'єкти. Сюди входять рядки, списки, кортежі та словники.


2
Наскільки надійно: hasattr(SomeClassWithoutGetItem, '__getitem__')визначити, чи можна підписати річ?
jmunsch

2
[... ]індексувати синтаксис називається індексом , тому що це рівносильно математичного запису , яка використовує фактичні індекси; наприклад a[1], Python для того, що математики писали б як a₁ . Отже, "підписується" означає "можливість підписатися". Що, з точки зору Python, означає, що воно має реалізовуватися __getitem__(), оскільки a[1]це просто синтаксичний цукор для a.__getitem__(1).
Марк Рід

Цей заклик hasattrповинен працювати добре, але це не піфонічний спосіб робити речі; Практика пітона заохочує друкувати качок . Тобто, якщо ви плануєте спробувати витягнути предмет з вашого об'єкта за допомогою підписника, продовжуйте робити це; якщо ви думаєте, що він може не працювати, оскільки об’єкт не піддається підключенню, оберніть його в tryблок із символом except TypeError.
Марк Рід

77

Нижче перелічені єдині вбудовані модулі, які можна підписати:

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__можна підписати


17

Об'єкт сценарію - це об'єкт, який записує виконані ним операції, і він може зберігати їх як "сценарій", який можна відтворити.

Наприклад, див .: Рамка сценаріїв додатків

Тепер, якщо Алістер не знав, про що він запитував, і справді мав на увазі "передплачувані" об'єкти (як редагували інші), то (як мипаді також відповів) це правильний варіант:

Об'єкт, що підписується - це будь-який об’єкт, який реалізує __getitem__спеціальний метод (списки розслідувань, словники).


2
Зауважте, що я відповідаю на початкове запитання про "сценарії" об'єктів, а не "підписувані", як редагували інші, а не Alistair. Я дуже хотів би прокоментувати Алістер.
тзот

Ах, новий знак моєї колекції! :) Просто жартую, очевидно. Єдине, що виправдовувало редагування питання, - це те, що Алістер обрав відповідь; Я досі не впевнений, чи впевнений Алістер у виборі.
цот

16

Сенс індексу в обчислювальних технологіях полягає в тому, що "символ (умовно написаний як підпис, але на практиці зазвичай не використовується), який використовується в програмі самостійно або з іншими, щоб вказати один з елементів масиву".

Тепер, у простому прикладі, поданому від @ user2194711, ми бачимо, що додаючий елемент не може бути частиною списку через дві причини: -

1) метод насправді не викликає додавання; тому що його потрібно ()називати.

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: об’єкт 'izgrain__function_or_method' не піддається підключенню


7

У мене був цей самий випуск. я робив

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

Тож використання [викликало помилки. Вона повинна бутиarr.append("HI")


3

Як наслідок попередніх відповідей тут, дуже часто це знак того, що ви вважаєте, що у вас є список (або диктант, або інший об'єкт, який можна підписати), коли цього немає.

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

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об'єкта не subscriptable» , тому що, ну, 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)пастку це теж.)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.