Мой вопрос:
Кажется, что __getattr__
не вызывается для операций индексации, т.е. я не могу использовать __getattr__
в классе A
для предоставления A[...]
. Есть причина для этого? Или способ обойти это, чтобы __getattr__
мог предоставлять эту функциональность без необходимости явно определять __getitem__
, __setitem__
и т. д. на A
?
Минимальный пример:
Допустим, я определяю два почти идентичных класса, Explicit
и Implicit
. Каждый создает небольшой список self._arr
при инициации, и каждый определяет __getattr__
, который просто передает все запросы атрибутов self._arr
. Единственное отличие состоит в том, что Explicit
также определяет __getitem__
(просто передавая его self._arr
).
# Passes all attribute requests on to a list it contains
class Explicit():
def __init__(self):
self._arr=[1,2,3,4]
def __getattr__(self,attr):
print('called __getattr_')
return getattr(self._arr,attr)
def __getitem__(self,item):
return self._arr[item]
# Same as above but __getitem__ not defined
class Implicit():
def __init__(self):
self._arr=[1,2,3,4]
def __getattr__(self,attr):
print('called __getattr_')
return getattr(self._arr,attr)
Это работает так, как ожидалось:
>>> e=Explicit()
>>> print(e.copy())
called __getattr_
[1, 2, 3, 4]
>>> print(hasattr(e,'__getitem__'))
True
>>> print(e[0])
1
Но это не так:
>>> i=Implicit()
>>> print(i.copy())
called __getattr_
[1, 2, 3, 4]
>>> print(hasattr(i,'__getitem__'))
called __getattr_
True
>>> print(i.__getitem__(0))
called __getattr_
1
>>> print(i[0])
TypeError: 'Implicit' object does not support indexing
__getattr__
используется для доступа к атрибутам, а__getitem__
используется для доступа к индексации. У каждого есть определенная роль. Я не уверен, в чем вопрос - person 3Doubloons   schedule 04.01.2017d = {'keys': 0}
В этом случаеd.keys
иd['keys']
— это очень разные вещи. - person 3Doubloons   schedule 04.01.2017Implicit
приводит к доступу к индексу одного из его членов? это вообще не имеет смысла. - person Jean-François Fabre   schedule 04.01.2017