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
)。也许例外会更好。
这段代码有什么问题?
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
)。也许例外会更好。