Why is AttributeError raised twice?
<pre><code>class ValidatingDB(object):
    def __init__(self):
       self.exists = 5

    def __getattribute__(self, name):
        print('Called __getattribute__(%s)' % name)
        try:
            return super(ValidatingDB, self).__getattribute__(name)
        except AttributeError:
            value = 'Value for %s' % name
            setattr(self, name, value)
            return value

data = ValidatingDB()
data.exists
data.foo
data.foo
</code></pre>

<p>I would expect that the first call to data.foo would "set" and the second call to data.foo would no longer produce the AttributeError.  Why does it raise the AttributeError for each call of data.foo?</p>

<p>Your code doesn't allow you to see the difference between an <code>AttributeError</code> and an attribute existing. In both cases you get <em>exactly the same result</em>.</p>

<p>So the first <code>data.foo</code> access raises an <code>AttributeError</code>, so a new value is created, set <em>and returned</em>.</p>

<p>The second <code>data.foo</code> access returns that value you already set. This is indistinguishable from the previous expression because <em>in both cases you get a value back</em>.</p>

<p>You'd have to change your code do something <em>else</em> when an <code>AttributeError</code> has been raised. You could add an extra <code>print</code> statement, for example:</p>

<pre><code>def __getattribute__(self, name):
    print('Called __getattribute__(%s)' % name)
    try:
        return super(ValidatingDB, self).__getattribute__(name)
    except AttributeError:
        print('No such attribute, generating a new value')
        value = 'Value for %s' % name
        setattr(self, name, value)
        return value
</code></pre>

<p>Now you'll see a difference:</p>

<pre><code>&gt;&gt;&gt; data = ValidatingDB()
&gt;&gt;&gt; data.exists
Called __getattribute__(exists)
5
&gt;&gt;&gt; data.foo
Called __getattribute__(foo)
No such attribute, generating a new value
'Value for foo'
&gt;&gt;&gt; data.foo
Called __getattribute__(foo)
'Value for foo'
</code></pre>

python python-2.7