How does __setattr__ work with class attributes?
<p>I am trying to understand how exactly __setattr__ works with class attributes. This question came about when I had attempted to override __setattr__ to prevent attributes from being written to in a simple class.</p>

<p>My first attempt used instance level attributes as follows:</p>

<pre><code>class SampleClass(object):

    def __init__(self):
        self.PublicAttribute1 = "attribute"

    def __setattr__(self, key, value):
        raise Exception("Attribute is Read-Only")
</code></pre>

<p>I had originally thought that only external attempts to set the attribute would throw an error, but even the statement inside the __init__ caused the exception to be thrown.</p>

<p>Later I ended up finding another way to do this, while attempting to solve a different problem. What I ended up with was:</p>

<pre><code>class SampleClass(object):
    PublicAttribute1 = "attribute"

    def __setattr__(self, key, value):
        raise Exception("Attribute is Read-Only")
</code></pre>

<p>I expected to get the same result, but to my surpirse I was able to set the class attribute while preventing changes from being made after the initial declaration. </p>

<p>I don't understand why this works though. I know it has to do with class vs. instance variables. My theory is that using __setattr__ on a class variable will create an instance variable of the same name, since I believe I think I have seen this behavior before, but I am not sure.</p>

<p>Can anyone explain exactly what is happening here?</p>

<p>Unless I'm missing something here, the answer is quite obvious: the first case has an attribute assignment which triggers the <code>__setattr__</code> method, in the line:</p>

<pre><code>self.PublicAttribute1 = "attribute"
</code></pre>

<p>But the second case has no such attribute assignment.  </p>

python