PropertyFactory

free_properties.PropertyFactory(fget=None, fset=None, clsname=None, doc=None, units=None, slots=None)[source]

Create an FreeProperty subclass with getter and setter functions.

fget : function, optional
Should return value of instances. If not given, a decorator expecting fget will be returned.
fset : function, optional
Should set the value of instances.
clsname : str, optional
Name of the class. Defaults to the function name of fget.
doc : str, optional
Docstring of class. Defaults to the docstring of fget.
units : str, optional
Units of measure.
slots : tuple[str], optional
Slots for class.

The PropertyFactory is a FreeProperty class creator that functions similar to Python ‘property’ objects. Use the PropertyFactory to create a Weight class which calculates weight based on density and volume:

>>> from free_properties import PropertyFactory
>>> def getter(self):
...    '''Weight (kg) based on volume (m^3).'''
...    data = self.data
...    rho = data['rho'] # Density (kg/m^3)
...    vol = data['vol'] # Volume (m^3)
...    return rho * vol
>>>
>>> def setter(self, weight):
...    data = self.data
...    rho = data['rho'] # Density (kg/m^3)
...    data['vol'] = weight / rho
>>>
>>> # Initialize with a value getter, setter, and the class name.
>>> Weight = PropertyFactory(fget=getter, fset=setter, clsname='Weight', units='kg')

It is more convinient to use the PropertyFactory as a decorator:

>>> @PropertyFactory(units='kg')
>>> def Weight(self):
...    '''Weight (kg) based on volume (m^3).'''
...    data = self.data
...    rho = data['rho'] # Density (kg/m^3)
...    vol = data['vol'] # Volume (m^3)
...    return rho * vol
>>>
>>> @Weight.setter
>>> def Weight(self, weight):
...    data = self.data
...    rho = data['rho'] # Density (kg/m^3)
...    data['vol'] = weight / rho

Create dictionaries of data and initialize new Weight objects:

>>> water_data = {'rho': 1000, 'vol': 3}
>>> ethanol_data = {'rho': 789, 'vol': 3}
>>> weight_water = Weight('Water', water_data)
>>> weight_ethanol = Weight('Ethanol', ethanol_data)
>>> weight_water
<Water: 3000 kg>
>>> weight_ethanol
<Ethanol: 2367 kg>

Note

The units are taken from the the function docstring. The first word in parentesis denotes the units.

These properties behave just like their dynamic value:

>>> weight_water + 30
3030
>>> weight_water + weight_ethanol
5367

Get and set the value through the ‘value’ attribute:

>>> weight_water.value
3000
>>> weight_water.value = 4000 
>>> weight_water.value
4000.0
>>> water_data # Note that the volume changed too
{'rho': 1000, 'vol': 4.0}

In place magic methods will also change the property value:

>>> weight_water -= 1000
>>> weight_water
<Water: 3000 kg>
>>> water_data  # The change also affects the original data
{'rho': 1000, 'vol': 3.0}