Python property does not use setter when setting the value in the constructor
Question:
I have a class with a constructor and a couple of properties
class Foo(object):
def __init__(self, value1):
self._value1 = value1
@property
def value1(self):
return self._value1
@property.setter
def value1(self, value):
assert value == 1
self._value1 = value
Now when I set value1 in on creation of the object the setter is not used. I noticed this because assertions were not called when entering the wrong values.
How can I make the values set in the constructor make use of the setter?
Answers:
You’re explicitly bypassing the setter by setting the underlying variable, rather than using the property. Drop the underscore.
def __init__(self, value1):
self.value1 = value1
Solution:
class Foo(object):
def __init__(self, value1 = 0):
self.value1 = value1 # Calling Set Property
@property
def value1(self):
return self.__value1
@property.setter
def value1(self, value):
assert value == 1
self.__value1 = value
A few other examples:
Example 1
class Product(object):
def __init__(self, price = 0.0):
self.price = price
def get_price(self):
return self.__price
def set_price(self, value):
if value < 0:
raise ValueError("Price cannot be negative")
self.__price = value
price = property(get_price, set_price)
Example 2
class Product(object):
def __init__(self, price = 0.0, name = ""):
self.price = price
self.name = name
# property for __price attribute
@property
def price(self):
return self.__price
@price.setter
def price(self, value):
if value < 0:
raise ValueError("Price cannot be negative")
self.__price = value
# property for __name attribute
@property
def name(self):
return self.__name
@name.setter
def name(self, value):
for ch in value:
if ch.isdigit():
raise Exception("Enter valid product name")
self.__name = value
I have a class with a constructor and a couple of properties
class Foo(object):
def __init__(self, value1):
self._value1 = value1
@property
def value1(self):
return self._value1
@property.setter
def value1(self, value):
assert value == 1
self._value1 = value
Now when I set value1 in on creation of the object the setter is not used. I noticed this because assertions were not called when entering the wrong values.
How can I make the values set in the constructor make use of the setter?
You’re explicitly bypassing the setter by setting the underlying variable, rather than using the property. Drop the underscore.
def __init__(self, value1):
self.value1 = value1
Solution:
class Foo(object):
def __init__(self, value1 = 0):
self.value1 = value1 # Calling Set Property
@property
def value1(self):
return self.__value1
@property.setter
def value1(self, value):
assert value == 1
self.__value1 = value
A few other examples:
Example 1
class Product(object):
def __init__(self, price = 0.0):
self.price = price
def get_price(self):
return self.__price
def set_price(self, value):
if value < 0:
raise ValueError("Price cannot be negative")
self.__price = value
price = property(get_price, set_price)
Example 2
class Product(object):
def __init__(self, price = 0.0, name = ""):
self.price = price
self.name = name
# property for __price attribute
@property
def price(self):
return self.__price
@price.setter
def price(self, value):
if value < 0:
raise ValueError("Price cannot be negative")
self.__price = value
# property for __name attribute
@property
def name(self):
return self.__name
@name.setter
def name(self, value):
for ch in value:
if ch.isdigit():
raise Exception("Enter valid product name")
self.__name = value