flybonzai flybonzai - 1 year ago 64
Python Question

Running super().__init__(value) where value is an @property

I'm just trying to grok how exactly Python handles this behind the scenes. So take this code snippet (from Effective Python by Brett Slatkin):

class Resistor(object):
def __init__(self, ohms):
self.ohms = ohms
self.voltage = 0
self.current = 0

class VoltageResistor(Resistor):
def __init__(self, ohms):
self._voltage = 0

def ohms(self):
return self._ohms

def ohms(self, ohms):
if ohms <= 0:
raise ValueError('{o} ohms must be > 0'.format(o=ohms))
self._ohms = ohms

def voltage(self):
return self._voltage

def voltage(self, voltage):
self._voltage = voltage
self.current = self._voltage / self.ohms

VoltageResistor(-1) # fails

Running the
call invokes the property check so that you can't instantiate with a zero or negative value. What is confusing me to me is that I would think that since the the
call is being ran on the superclass, shouldn't it be in a different scope (the scope of the superclass) and thus exempt from invoking the

Answer Source

Scope doesn't come into play when working with object's attributes. Consider the following:

class A(object):
    def __init__(self):
        self.a = 1

def foo():
    a = A()
    a.a = 2
    return a

def bar(a):


This example code will print 2. Note that within the scope of bar, there is no way to gain access to the scope of foo or even A.__init__. The class instance is carrying along all of it's attributes/properties with it (and a reference to it's class which has a reference to it's superclass, etc).

In your code, when you call VoltageResistor, an instance of VoltageResistor is created and passed to __init__ as self. When you call super.__init__(self), that VoltageResistor instance is passed along to Resistor.__init__. When it does self.ohms = ohms, python sees that self.ohms resolves to a property and you get the error. The tl;dr; here is that self is an instance of VoltageResistor and when working with attributes, the object on which the attributes are accessed is what is important, not the current scope).