__getattr__在其他对象的getattr()上返回不同的id

时间:2015-04-15 15:04:50

标签: python python-2.7

在尝试实现对象包装器时,我偶然发现了python中的奇怪行为。请考虑以下代码(我已经从我遇到的案例中简化了它以展示其基础知识):

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()

上述脚本的输出将是:

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

注意每当调用__getattr__(第一行打印)时,id如何在两个值之间切换?我已经搞砸了一下,这也发生在__getattribute__上,但请注意,在调用regular_func时它永远不会发生。它总是在两个值之间切换,并且总是切换(而不是随机)。

即使我将__getattr__更改为:

,这仍然会发生
a=A()
class B(object):
    def __getattr__(self, attr):
        return getattr(a, attr)

或者这样:

a=A()
class B(object):
    def __getattr__(self, attr):
        return a.__getattribute__(attr)

在上面的例子中,重复打印id(a.__getattribute__("hello"))总是给出相同的数字。

任何人都可以解释这种奇特的行为,或建议任何进一步的想法来调查吗?

0 个答案:

没有答案