【问题标题】:Why does __getattribute__ not work with some values?为什么 __getattribute__ 不适用于某些值?
【发布时间】: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.nameself.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.attrtype(self).__getattribute__(self, attr) 是一样的,type(self) 这里是Product

标签: python class oop getattribute


【解决方案1】:

蟒蛇documentation 说:

object.__getattribute__(self, name)

无条件调用以实现类实例的属性访问。如果该类还定义了__getattr__(),则不会调用后者,除非__getattribute__() 显式调用它或引发AttributeError。

此方法应返回(计算的)属性值或引发 AttributeError 异常。

为了避免这个方法无限递归,它的实现应该总是调用同名的基类方法来访问它需要的任何属性,例如,object.__getattribute__(self, name)

【讨论】:

    猜你喜欢
    • 2015-12-10
    • 1970-01-01
    • 2020-10-29
    • 2013-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-28
    • 2020-08-05
    相关资源
    最近更新 更多