【发布时间】:2017-04-18 08:18:44
【问题描述】:
我的问题是关于__getattribute__。请考虑以下代码:
class Product():
def __init__(self, name, quantity = 1, price = 0.0):
self.name = name
self.quantity = quantity
self.price = price
def __getattribute__(self, attr):
if (attr == 'price'):
return 30 * object.__getattribute__(self, attr)
#change object.blala-la to the self.name or self.quantity
else:
return object.__getattribute__(self, attr)
tmp = Product("Watermelon", 2, 50.0);
print(tmp.price)
我发现有点误导,如果我将 object.__getattribute__(self, attr) 更改为 self.name 或 self.quantity 我将得到 30 次字符串“西瓜”或 60.0(如果是 self.quantity),但如果我放在那里self.price 我会得到 RuntimeError,关于最大递归深度的东西。
所以,问题:为什么我不能用self.price 来做,而只写object.__getattribute__(self, attr)?
【问题讨论】:
-
你觉得
self.price用在__getattribute__中时做什么?__getattribute__被调用用于 all 属性访问,即使是在同一方法内执行的属性访问。所以self.price会调用__getattribute__,它访问self.price,它调用__getattribute__,无穷无尽。或者直到运行时错误。 -
好的,我想我明白了。
object.__getattribute__(self, attr(*price*))就像一个中断语句,用于无休止地访问 self.price。对吗? -
不,你委托给原来的
object.__getattribute__实现。该实现不调用self.__getattribute__,因此不存在递归问题。 -
所以,我们不输入
self.attr而是写object.__getattribute__(self, attr)以避免无限递归,因为它会敲入object Class中的getattribute 方法定义,从而中断递归?但是,如果我们在if-else中输入类似return Product.__getattribute(self, attr)或return self.attr的内容,那么我们将调用下一次递归迭代? -
是的,因为两者都会再次调用
Product.__getattribute__。self.attr和type(self).__getattribute__(self, attr)是一样的,type(self)这里是Product。
标签: python class oop getattribute