Mallow Mallow - 8 days ago 7
Python Question

Why can't @var.setter function access class variables?

I have a class where I want to validate the data whenever it's property is changed. I wish to store the valid options as a class variable that the setter can refer to, but I seem to have found that within the

@var.setter
option I'm unable to reference any class variables at all.

Why is that?

Code example:

class Standard():
def __init__(self):
self.variable1 = 1
self.variable2 = 2

@property
def variable1(self):
# This works
print(self.variable2)
return self.__variable1

@variable1.setter
def variable1(self, var):
# This doesn't work
print(self.variable2)
self.__variable1 = var

x = Standard()
print(x.variable1)
x.variable1 = 4
print(x.variable1)


This outputs:

AttributeError: 'Standard' object has no attribute 'variable2'


When it clearly does.

Answer

You are first setting variable1 in __init__:

def __init__(self):
    self.variable1 = 1
    self.variable2 = 2

Since self.variable1 is handled by @variable1.setter, variable2 can't yet exist at that time. You could swap the two lines:

def __init__(self):
    self.variable2 = 2
    self.variable1 = 1

Now variable2 is properly set before variable1.setter runs.

Alternatively, give variable2 a class attribute to act as a default:

class Standard():
    # ...

    variable2 = 'class default'

    @variable1.setter
    def variable1(self, var):
        print(self.variable2)
        self.__variable1 = var

or use getattr() on self:

@variable1.setter
def variable1(self, var):
    print(getattr(self, 'variable2', 'not available yet'))
    self.__variable1 = var

or set __variable1 directly, bypassing the setter:

class Standard():
    def __init__(self):
        self.__variable1 = 1  # don't use the setter
        self.variable2 = 2