Why is it considered bad practice to hardcode the name of a class inside that class's methods?
<p>In python, why is it a bad thing to do something like this:</p>

<pre><code>class Circle:
  pi = 3.14159 # class variable
  def __init__(self, r = 1):
    self.radius = r
  def area(self):
    return Circle.pi * squared(self.radius)

def squared(base): return pow(base, 2)
</code></pre>

<p>The area method could be defined as follows:</p>

<pre><code>def area(self): return self.__class__.pi * squared(self.radius) 
</code></pre>

<p>which is, unless I'm very much mistaken, considered a better way to reference a class variable. The question is why? Intuitively, I don't like it but I don't seem to completely understand this.</p>

<blockquote>
  <p>Why is it considered bad practice to hardcode the name of a class inside that class's methods?</p>
</blockquote>

<p><strong>It's not.</strong> I don't know why you think it is.</p>

<p>There are plenty of good reasons to hardcode the name of a class inside its methods. For example, using <code>super</code> on Python 2:</p>

<pre><code>super(ClassName, self).whatever()
</code></pre>

<p>People often try to replace this with <code>super(self.__class__, self).whatever()</code>, and they are <strong>dead wrong</strong> to do so. The first argument <strong>must</strong> be the actual class the <code>super</code> call occurs in, not <code>self.__class__</code>, or the lookup will find the wrong method.</p>

<p>Another reason to hardcode the class name is to avoid overrides. For example, say you've implemented one method using another, as follows:</p>

<pre><code>class Foo(object):
    def big_complicated_calculation(self):
        return # some horrible mess
    def slightly_different_calculation(self):
        return self.big_complicated_calculation() + 2
</code></pre>

<p>If you want <code>slightly_different_calculation</code> to be independent of overrides of <code>big_complicated_calculation</code>, you can explicitly refer to <code>Foo.big_complicated_calculation</code>:</p>

<pre><code>def slightly_different_calculation(self):
    return Foo.big_complicated_calculation(self) + 2
</code></pre>

<p>Even when you <em>do</em> want to pick up overrides, it's usually better to change <code>ClassName.whatever</code> to <code>self.whatever</code> instead of <code>self.__class__.whatever</code>.</p>

python oop