I've stumbled upon a curious behavior in python while trying to implement an object wrapper. Consider the following code (I've simplified it from the case I've encountered to show its very basics):
class A(object):
def hello(self):
print "hello ",
class B(object):
def __init__(self, obj):
self.obj = obj
def __getattr__(self, attr):
return getattr(self.obj, attr)
def regular_func(self, attr):
return getattr(self.obj, attr)
a=A()
b=B(a)
for x in xrange(10):
print id(b.hello), ",",
print
for x in xrange(10):
print id(a.hello), ",",
print
for x in xrange(10):
print id(A.hello), ",",
print
for x in xrange(10):
print id(b.regular_func("hello")), ",",
print
for x in xrange(10):
b.hello()
The output of the above script will be:
4375335072 , 4375100144 , 4375335072 , 4375100144 , 4375335072 , 4375100144 , 4375335072 , 4375100144 , 4375335072 , 4375100144 ,
4375100144 , 4375100144 , 4375100144 , 4375100144 , 4375100144 , 4375100144 , 4375100144 , 4375100144 , 4375100144 , 4375100144 ,
4375100144 , 4375100144 , 4375100144 , 4375100144 , 4375100144 , 4375100144 , 4375100144 , 4375100144 , 4375100144 , 4375100144 ,
4375100144 , 4375100144 , 4375100144 , 4375100144 , 4375100144 , 4375100144 , 4375100144 , 4375100144 , 4375100144 , 4375100144 ,
hello hello hello hello hello hello hello hello hello hello
Notice how the ids toggle between two values whenever the __getattr__
is invoked (the first row printed)? I've messed around with it a bit, this happens for __getattribute__
as well, but notice it never happens when calling regular_func
. It always toggles between two values, and always toggles (not randomly).
This still happens even when I change the __getattr__
to such:
a=A()
class B(object):
def __getattr__(self, attr):
return getattr(a, attr)
Or as such:
a=A()
class B(object):
def __getattr__(self, attr):
return a.__getattribute__(attr)
And in the above example, repeatedly printing id(a.__getattribute__("hello"))
always gives the same number.
Can anyone explain this peculiar behavior, or suggest any further ideas to investigate?