Properties in Python


Properties in Python

Python Object Properties

Python has a decorator called @property, which can be used to make an object method behave like an attribute.

class Klass:
    
    #private attribute:
    _prop = 0
    
    #private attribute exposed as a property
    @property
    def prop(self):
        return self._prop

This way, K.prop will return the value of _prop (note that the method is not invoked - it appears like a normal attribute).

Python Property Setters

This property is readonly, but we can also define a property setter - a method that can be used to assign a new value to our attribute:

class Klass:
    _prop = 0
    
    @property
    def prop(self):
        return self._prop
    
    @prop.setter
    def prop(self, val):
        self._prop = val

Example usage:

k = Klass()
print(k.prop) # output: 0
print(k._prop) # output: 0
k.prop = 3
print(k.prop) # output: 3
print(k._prop) # output: 3

Common use cases for properties

The above example are not very useful in themselves, but properties are quite powerful tools. They can be used to dynamically generate values or validate attribute values on assignment.

For example:

class Payment:
    VALID_CURRENCIES = "USD", "GBP", "EUR"
    
    amount = 0
    _currency = ""
    
    @property
    def currency(self):
        return self._currency
    
    @currency.setter
    def currency(self, currency):
        new_currency = currency.upper()
        if new_currency not in self.VALID_CURRENCIES:
            raise ValueError("Invalid currency: {}".format(currency))
        self._currency = new_currency

Example usage:

payment=Payment()
payment.currency = "blabla" # raises exception: ValueError: Invalid currency: blabla
payment.currency = "eur"
print(payment.currency) # output: EUR