Dave Kuhlman wrote: > The following code has me mystified: > > In [4]: class A(object): > ...: def show(self): > ...: print 'hello' > ...: > ...: > In [5]: a = A() > In [6]: > In [7]: x = a.show > In [8]: y = getattr(a, 'show') > In [9]: x > Out[9]: <bound method A.show of <__main__.A object at 0xb557d0>> > In [10]: y > Out[10]: <bound method A.show of <__main__.A object at 0xb557d0>> > In [11]: > In [12]: id(x) > Out[12]: 12419552 > In [13]: id(y) > Out[13]: 12419872 > In [14]: > In [15]: x is y > Out[15]: False > In [16]: > In [17]: x() > hello > In [18]: y() > hello > > Basically, the above code is saying that foo.foobar is not the same as > getattr(foo, 'foobar'). > > But the documentation at > http://docs.python.org/lib/built-in-funcs.html#l2h-33 > says that they are equivalent. > > And, the following seems even worse: > > >>> id(getattr(a, 'show')) == id(a.show) > True > >>> getattr(a, 'show') is a.show > False > > Actually, while I don't know about the basic problem, this doesn't mean id() is broken. In the comparison, an object is created, then id() is computed, and the object is garbage collected. The same happens to the second object. Since by the time it is created the first object was garbage collected, it can have the same id(). As you have already shown in your previous example, when the first object is not discarded, the id() is different. Here's some code to illustrate this:
In [17]: bla = [a.foo for x in range(5)] In [18]: bar = [id(z) for z in bla] In [19]: bar Out[19]: [138262924, 137884252, 137884212, 137884452, 137884572] (This result is equivalent for getattr(a,'foo').) > What gives? This breaks my understanding of id(), the is operator, and > getattr(). > > Can someone help me make sense of this? > > I'm using Python 2.5.2. > > - Dave > > Cheers, Imri ------------------------- Imri Goldberg www.algorithm.co.il/blogs www.imri.co.il ------------------------- Insert Signature Here ------------------------- -- http://mail.python.org/mailman/listinfo/python-list