【问题标题】:What is the reason for recursion?递归的原因是什么?
【发布时间】:2019-01-28 14:55:13
【问题描述】:

Difference between __getattr__ vs __getattribute__ 上,__getattr___getattribute__ 有一些很好的例子。

为什么__getattribute__ 在代码之后被调用了 19 次? 好的 - 这是一个递归......但是为什么呢?

class Count(object):

    def __init__(self,mymin,mymax):
        self.mymin=mymin
        self.mymax=mymax
        self.current=None

    def __getattr__(self, item):
            self.__dict__[item]=0
            return 0

    def __getattribute__(self, item):
        print("__getattribute__: ", item)          # only this line is new!!!!
        if item.startswith('cur'):
            raise AttributeError
        return object.__getattribute__(self,item)
        # or you can use ---return super().__getattribute__(item)
        # note this class subclass object

obj1 = Count(1,10)
print(obj1.mymin)
print(obj1.mymax)
print(obj1.current)
print("end")

输出:

__getattribute__:  mymin
1
__getattribute__:  mymax
10
__getattribute__:  current
__getattribute__:  __dict__
0
end
__getattribute__:  __class__
__getattribute__:  __class__
__getattribute__:  __class__
__getattribute__:  __class__
__getattribute__:  __class__
__getattribute__:  __class__
__getattribute__:  __class__
__getattribute__:  __class__
__getattribute__:  __class__
__getattribute__:  __class__
__getattribute__:  __class__
__getattribute__:  __class__
__getattribute__:  __class__
__getattribute__:  __class__
__getattribute__:  __class__
__getattribute__:  __class__
__getattribute__:  __class__
__getattribute__:  __class__
__getattribute__:  __class__

【问题讨论】:

  • 您好,我对您的代码格式做了一些更改(请检查它们是否符合您最初问题的意图)。不过,我似乎无法重现这一点……在 IDLE 上,end 之后没有输出。
  • 从您所展示的内容来看,除了构造函数之外,您永远不会调用 count 类中的任何函数。请详细说明 object is in class Count(object)
  • @ZWang 对print 的调用中的三个属性访问中的每一个都会触发对Count.__getattribute__ 的隐式调用
  • @MartinMeier 这可能与垃圾回收有关。
  • 对不起,我是个白痴

标签: python python-3.x recursion getattribute


【解决方案1】:

使用 CPython 3.7,我可以重现您的问题的唯一方法是在您的代码中放置断点并进行调试。

因此,对Count.__getattribute__ 的多次调用很可能是由尝试访问您的类属性的其他东西(在我的情况下:调试器)引起的。

作为记录,这是我以正常方式运行您的代码时的跟踪:

__getattribute__:  mymin
1
__getattribute__:  mymax
10
__getattribute__:  current
__getattribute__:  __dict__
0
end

请注意,即使访问obj1.current,也不会显示异常跟踪。这是我无法解释的具体行为。

【讨论】:

  • obj1.current 在 __getattribute__ 中引发 AttributeError。这在 Python 中被捕获,然后调用 __getattr__ 来解析未知属性。当 __getattr__ 也引发 AttributeError 时,您只会看到异常跟踪。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-04-10
  • 2011-04-13
  • 2020-10-10
  • 1970-01-01
  • 2016-08-28
  • 2016-09-01
  • 2011-12-04
相关资源
最近更新 更多