Dipende dalla tua intenzione.
In [1]: my_int = 5
In [2]: my_int.__getitem__(0) # -> AttributeError
In [3]: my_int[0] # -> TypeError
Quando si utilizza .
si chiama implicitamente la funzione getattr
, che solleva naturalmente il AttributeError
se l'attributo non esiste.
Aggiornamento 2. Diamo un'occhiata al bytecode.
In [11]: import dis
In [12]: def via_operator():
my_int = 5
my_int[0]
In [13]: def via_getattr():
my_int = 5
my_int.__getitem__(0)
In [14]: dis.dis(via_operator)
2 0 LOAD_CONST 1 (5)
3 STORE_FAST 0 (my_int)
3 6 LOAD_FAST 0 (my_int)
9 LOAD_CONST 2 (0)
12 BINARY_SUBSCR
13 POP_TOP
14 LOAD_CONST 0 (None)
17 RETURN_VALUE
In [15]: dis.dis(via_getattr)
2 0 LOAD_CONST 1 (5)
3 STORE_FAST 0 (my_int)
3 6 LOAD_FAST 0 (my_int)
9 LOAD_ATTR 0 (__getitem__)
12 LOAD_CONST 2 (0)
15 CALL_FUNCTION 1
18 POP_TOP
19 LOAD_CONST 0 (None)
22 RETURN_VALUE
Come si vede, il []
ha una speciale istruzione di virtual-machine. Dal docs
BINARY_SUBSCR: Implements TOS = TOS1[TOS].
Quindi è abbastanza naturale per sollevare un TypeError
, quando non si riesce ad eseguire un'istruzione.
Update 1: Guardando le getattr
fonti, è chiaro che questa funzione non può mai sollevare una tale TypeError
, quindi l'operatore []
non chiama sotto il cofano (per il built-in tipi, almeno, anche se è meglio trovare le fonti per chiarire questo bit).
static PyObject *
builtin_getattr(PyObject *self, PyObject *args)
{
PyObject *v, *result, *dflt = NULL;
PyObject *name;
if (!PyArg_UnpackTuple(args, "getattr", 2, 3, &v, &name, &dflt))
return NULL;
#ifdef Py_USING_UNICODE
if (PyUnicode_Check(name)) {
name = _PyUnicode_AsDefaultEncodedString(name, NULL);
if (name == NULL)
return NULL;
}
#endif
if (!PyString_Check(name)) {
PyErr_SetString(PyExc_TypeError,
"getattr(): attribute name must be string");
return NULL;
}
result = PyObject_GetAttr(v, name);
if (result == NULL && dflt != NULL &&
PyErr_ExceptionMatches(PyExc_AttributeError))
{
PyErr_Clear();
Py_INCREF(dflt);
result = dflt;
}
return result;
}
Se si accede a 'my_int .__ getitem__' direttamente, si ottiene un' AttributeError'. Ma * questo è un dettaglio di implementazione * - il problema che stai vedendo è che non supporta l'indicizzazione, che è un errore di tipo. – jonrsharpe
Si noti che il primo esempio fa riferimento a un attributo, mentre il secondo esempio fa riferimento a un elemento. –
Non c'è abc 'Indexable' (tutti i tipi di contenitori usano' __getitem__'), ma suppongo che 'TypeError' suppone che' int' non sia di alcun tipo che sia indicizzabile. – timgeb