title: Why is __getattr__ not called for indexing operations?
body: <p><strong>My question:</strong></p>
  
  <p>It seems that <code>__getattr__</code> is not called for indexing operations, ie I can't use <code>__getattr__</code> on a class <code>A</code> to provide <code>A[...]</code>.  Is there a reason for this? Or a way to get around it so that <code>__getattr__</code>  can provide that functionality without having to explicitly define <code>__getitem__</code>, <code>__setitem__</code>, etc on <code>A</code>?</p>
  
  <p><strong>Minimal Example:</strong></p>
  
  <p>Let's say I define two nearly identical classes, <code>Explicit</code> and <code>Implicit</code>.  Each creates a little list <code>self._arr</code> on initiation, and each defines a <code>__getattr__</code> that just passes all attribute requests to <code>self._arr</code>.  The only difference is that <code>Explicit</code> also defines <code>__getitem__</code> (by just passing it on to <code>self._arr</code>).</p>
  
  <pre><code># 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)
  </code></pre>
  
  <p>This works as expected:</p>
  
  <pre><code>&gt;&gt;&gt; e=Explicit()
  &gt;&gt;&gt; print(e.copy())
  called __getattr_
  [1, 2, 3, 4]
  &gt;&gt;&gt; print(hasattr(e,'__getitem__'))
  True
  &gt;&gt;&gt; print(e[0])
  1
  </code></pre>
  
  <p>But this doesn't:</p>
  
  <pre><code>&gt;&gt;&gt; i=Implicit()
  &gt;&gt;&gt; print(i.copy())
  called __getattr_
  [1, 2, 3, 4]
  &gt;&gt;&gt; print(hasattr(i,'__getitem__'))
  called __getattr_
  True
  &gt;&gt;&gt; print(i.__getitem__(0))
  called __getattr_
  1
  &gt;&gt;&gt; print(i[0])
  TypeError: 'Implicit' object does not support indexing
  </code></pre>