我只是想弄清楚Python究竟是如何在幕后处理这个问题的。因此,请看以下代码片段(来自Brett Slatkin的Effective Python):
class Resistor(object):
def __init__(self, ohms):
self.ohms = ohms
self.voltage = 0
self.current = 0
class VoltageResistor(Resistor):
def __init__(self, ohms):
super().__init__(ohms)
self._voltage = 0
@property
def ohms(self):
return self._ohms
@ohms.setter
def ohms(self, ohms):
if ohms <= 0:
raise ValueError('{o} ohms must be > 0'.format(o=ohms))
self._ohms = ohms
@property
def voltage(self):
return self._voltage
@voltage.setter
def voltage(self, voltage):
self._voltage = voltage
self.current = self._voltage / self.ohms
VoltageResistor(-1) # fails
运行super()
调用调用属性检查,这样就不能用零值或负值进行实例化。让我困惑的是,我认为既然__init__(ohms)
调用是在超类上运行的,那么它不应该在另一个作用域(超类的作用域)中,从而免于调用@property
检查吗?你知道吗
为了补充上述出色的答案,只需在父构造函数中添加以下行,就可以更好地了解发生了什么:
它将打印
VoltageResistor
,然后抛出一个ValueError
。Python docs确认这一点:在处理对象的属性时,作用域不起作用。考虑以下几点:
此示例代码将打印2。注意,在
bar
范围内,没有办法访问foo
范围,甚至A.__init__
。类实例携带着它的所有属性(以及对它的类的引用,该类引用引用了它的超类,等等)。你知道吗在您的代码中,当您调用
VoltageResistor
时,VoltageResistor
的实例被创建并作为self
传递给__init__
。调用super.__init__(self)
时,VoltageResistor
实例被传递给Resistor.__init__
。当它执行self.ohms = ohms
操作时,python会看到self.ohms
解析为一个属性,您就会得到错误。太长了,读不下去了,这里是^ {CD7}}是^ {< CD4}}和<强>的实例,当使用属性时,访问属性的对象是重要的,而不是当前的范围< /强>。你知道吗相关问题 更多 >
编程相关推荐