title: Identity equality for methods in a loop
body: <p>Consider the following code:</p>
  
  <pre><code>def a():
      pass
  
  def comp():
      for f in (a,):
          if f is a:
              print("Identity")
          elif f == a:
              print("Equality")
  
  comp()
  </code></pre>
  
  <p>I create a function <code>a</code>, and a function <code>comp</code> which checks, for all functions in the tuple <code>(a,)</code>, if they're either identical to <code>a</code> (<code>f is a</code>), or equal to it (<code>f == a</code>). Unsurprisingly, this code prints the word "Identity".</p>
  
  <p>However, this is no longer the case if I turn those functions into instance methods of a class <code>Test</code>:</p>
  
  <pre><code>class Test(object):
      def a(self):
          pass
  
      def comp(self):
          for f in (self.a,):
              if f is self.a:
                  print("Identity")
              elif f == self.a:
                  print("Equality")
  
  t = Test()
  t.comp()
  </code></pre>
  
  <p>To my great surprise, this prints "Equality" instead of "Identity". Indeed, if we put <code>print(id(f), id(self.a))</code> inside the <code>for</code> loop, it will print different identity values. As I'd expect, both identities are different from <code>id(Test.a)</code>.</p>
  
  <p>Why is this? Why do the methods seemingly get copied by the for loop, when the plain functions do not?</p>