Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>When you ask for an attribute of an instance which is a function, you get a <em>bound method</em>: a callable object which wraps the function defined in the class and passes the instance as the first argument. In Python 2.x, when you ask for an attribute of a class which is a function you get a similar proxy object called an <em>unbound method</em>:</p> <pre><code>&gt;&gt;&gt; class A: m = lambda: None ... &gt;&gt;&gt; A.m &lt;unbound method A.&lt;lambda&gt;&gt; </code></pre> <p>This special object is created when you ask for it, and not apparently cached anywhere. That means that when you do</p> <pre><code>&gt;&gt;&gt; A.m is A.m False </code></pre> <p>you are creating two <em>distinct</em> unbound method objects and testing them for identity.</p> <p>Notice that</p> <pre><code>&gt;&gt;&gt; x = A.m &gt;&gt;&gt; x is x True </code></pre> <p>and</p> <pre><code>&gt;&gt;&gt; A.m.im_func is A.m.im_func True </code></pre> <p>work fine. (<code>im_func</code> is the original function which the unbound method object is wrapping.)</p> <p>In Python 3.x, incidentally, <code>C.m is C.m</code> is True, because the (somewhat pointless) unbound method proxy objects were removed entirely and you just get the original function which you defined.</p> <hr> <p>This is just one example of the very dynamic nature of attribute lookup in Python: when you ask for an attribute of an object, it is possible to run arbitrary Python to calculate the value of that attribute. Here's another example where your test fails in which it is much clearer why:</p> <pre><code>&gt;&gt;&gt; class ChangingAttribute(object): ... @property ... def n(self): ... self._n += 1 ... return self._n ... ... def __init__(self): ... self._n = 0 ... &gt;&gt;&gt; foo = ChangingAttribute() &gt;&gt;&gt; foo.n 1 &gt;&gt;&gt; foo.n 2 &gt;&gt;&gt; foo.n 3 &gt;&gt;&gt; foo.n is foo.n False &gt;&gt;&gt; foo.n 6 </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload