Python“__setattr__”和“__getattribute__”混淆

Python "__setattr__" and "__getattribute__" confusion

这段代码有什么问题?

class Spam(object):

    def __init__(self, a, b):
        self.a = a
        self.b = b

    # using this to mark field "c" as deprecated. As per my understanding this gets called only for fields that do not exist.
    def __getattr__(self, c):
        print("Deprecated")

    # using this to manipulate the value before storing
    def __setattr__(self, name, value):
        self.__dict__[name] = value + 1

    # interceptor to allows me to define rules for whenever an attribute's value is accessed
    def __getattribute__(self, name):
        return self.__dict__[name] 

spam = Spam(10, 20)

print(spam.a)
print(spam.b)
print(spam.c)

但是上面的代码没有打印任何东西。这里有什么问题,任何人都可以帮助我理解这一点吗?我在 https://rszalski.github.io/magicmethods/#access

中了解了这些方法

But the above code doesn't print anything

错了。它因无限递归而崩溃。

__getattribute__中,当你想log/intercept调用的时候,在某些时候你还是想得到原来的方法来获取属性。 self.__dict__[name] 调用 __getattribute__ 所以这不是正确的方法。

您正在尝试再次调用此方法,您将获得无限递归。改为调用 parent/base 方法:

# interceptor to allows me to define rules for whenever an attribute's value is accessed
def __getattribute__(self, name):
    return object.__getattribute__(self,name)  # or super(Spam,self).__getattribute__(name)

打印:

11
21
Deprecated
None

None__getattr__ 返回(因为它只是打印到控制台并隐含 returns None)。也许例外会更好。