В чем причина рекурсии? - PullRequest
0 голосов
/ 28 января 2019

Вкл. Разница между __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__

1 Ответ

0 голосов
/ 28 января 2019

В CPython 3.7 единственный способ воспроизвести вашу проблему - это поставить точку останова и отладить ваш код.

Итак, множественные вызовы Count.__getattribute__, скорее всего, вызваны чем-то другим (в моем случае: отладчик), который пытается получить доступ к вашим атрибутам класса.

Для записи, вот трассировка, когда я запускаю ваш код обычным способом:

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

Обратите внимание, что нетТрассировка исключений отображается даже при обращении к obj1.current.Это специфическое поведение, которое я не могу объяснить.

...