Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I restructured your example a little to better illustrate the variants I'll use to explain the behaviour</p> <h3><a href="http://ideone.com/TWdgk" rel="nofollow">With temporary variables</a></h3> <pre><code>import inspect def print_id(obj): print "{} =&gt; {}".format(id(obj), obj) def getmember(obj, name): #members = dict(inspect.getmembers(obj)) #return members[name] return [member for _name, member in inspect.getmembers(obj) if name == _name][0] class Foo(object): def bar(self): pass foo = Foo() m1 = foo.bar m2 = getattr(foo, 'bar') m3 = getmember(foo, 'bar') print_id(m1) print_id(m2) print_id(m3) </code></pre> <p>However, if you inspect objects in a REPL, the basic structure of your code will probably look like this:</p> <h3><a href="http://ideone.com/eGr5T" rel="nofollow">Without temporary variables</a></h3> <pre><code>#... foo = Foo() print_id(foo.bar) print_id(getattr(foo, 'bar')) print_id(getmember(foo, 'bar')) </code></pre> <p>The <code>id()</code> function basically returns the memory address of an object. That is, it's not an identity that's unique between all objects created during the whole runtime of a program. It's only unique between all the objects that exist in the process at any given point in time.</p> <p>The explanation that fits the difference between the two examples is that resolving <code>foo.bar</code> in any of the three ways gives you <strong>a new object every time</strong>. In the first example, these objects are stored in temporary variables, so all three have to be located at different memory addresses.</p> <p>In the second example, the bound method object is no longer needed after it's printed out; the Python reference counting GC will free its memory. This means that the next time the bound method object is created, it's a new object that happens to get created at the same memory address as the previous one. This is why it can seem like you're getting the same object multiple times.</p> <p>That you always get a new bound method object can be shown trivially:</p> <pre><code>&gt;&gt;&gt; foo.bar == foo.bar True &gt;&gt;&gt; foo.bar is foo.bar False </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