Package: numprops
Please note:this package is experimental and may still see some
changes to the API. If you have any suggestions for improving the API,
please open an issue!AboutThis simple module defines a descriptor class that can be used to define
numerical properties (scalar and n-dimensional arrays) on classes and
provide a way to validate these. Thus, instead of writing something
like:classSphere(object):@propertydefradius(self):returnself._radius@radius.setterdefradius(self,value):ifvalue<=0:raiseValueError("Value should be strictly positive")ifnotnp.isscalar(value):raiseTypeError("Value should be a scalar")ifnotnp.isreal(value):raiseTypeError("Value should be numerical")self._value=valuefor each property you want to define, you can simply do:fromnumpropsimportNumericalPropertyclassSphere(object):radius=NumericalProperty('radius',domain='strictly-positive',ndim=0)Support is also included for checking the dimensionality and shape of
arrays (which includes converting tuples and lists to arrays
on-the-fly), as well as checking the units of quantities for theastropy.units,pint, andquantitiesunit frameworks.InstallingThis package is compatible with Python 2.6, 2.7, and 3.3 and later, and
requiresnumpy. If you are interested in
doing unit validation, you will also needastropy,pint, orquantities, depending on
which unit framework you normally use.To install, you can do:pip install numpropsYou can also bundlenumprops.pyinto your package if you want to
avoid using an external dependency, but please be sure to keep the
copyright and the license for the file.UsingTo create self-validating numerical properties on a class, use theNumericalPropertyclass:fromnumpropsimportNumericalPropertyclassSphere(object):radius=NumericalProperty('radius',domain='strictly-positive',ndim=0)position=NumericalProperty('position',shape=(3,))When a property is set, it will be validated:>>>s=Sphere()>>>s.radius=1.>>>s.radius=-3...ValueError:radiusshouldbestrictlypositive>>>s.radius=[1,2]...TypeError:radiusshouldbeascalarvalue>>>s.position=(1,2,3)>>>s.position=3...TypeError:positionshouldbea1-dsequence>>>s.position=(1,2,3,4)...ValueError:positionhasincorrectlength(expected3butfound4)The following arguments toNumericalPropertyare available (in
addition to the property name):ndim: restrict the values to arrays with this number of dimensionshape: restrict the values to arrays with this shape. If
specified,ndimdoes not need to be given.domain: restrict the values to a particular domain - can be one
ofpositive,strictly-positive,negative,strictly-negative, or a tuple representing a range of values.default: the default value to return, if not specified (defaults
toNone)convertible_to: restrict the values to ones with units that would
be convertible to a specific set of units (see section below)Note that tuples and lists will automatically get converted to Numpy
arrays, if they are considered valid.Physical unitsWhileNumericalPropertycan be used for plain scalars and Numpy
arrays, it can also be used for scalars and arrays which have associated
units, with support for three popular unit handling units:astropy.units,pint, andquantities.To restrict aNumericalPropertyto quantities with a certain type of
unit, use theconvertible_tooption. This option takes units from
any of these three unit packages, and will ensure that any value passed
has units equivalent (but not necessarily equal) to those specified with
theconvertible_tooption.If the units passed toconvertible_toareastropy.unitsunits, then any
value passed to the property should then be anastropy.unitsquantity. If the
units passed toconvertible_toarepintunits, then any quantity passed
to the property should be apintproperty. And finally if the units passed toconvertible_toarequantitiesunits, then any
quantity passed to the property should be aquantitiesquantity.astropy.units Quantity exampleThe following example shows how to restrict theradiusproperty to
be anastropy.unitsquantity in
units of length:fromastropyimportunitsasuclassSphere(object):radius=NumericalProperty('radius',convertible_to=u.m)will then behave as follows:>>>s=Sphere()>>>s.radius=3.*u.m>>>s.radius=4.*u.cm>>>s.radius=4.*u.s...ValueError:radiusshouldbeinunitsconvertibletompint Quantity exampleThe following example shows how to restrict theradiusproperty to
be apintquantity in units of
length:frompintimportUnitRegistryureg=UnitRegistry()classSphere(object):radius=NumericalProperty('radius',convertible_to=ureg.m)will then behave as follows:>>>s=Sphere()>>>s.radius=3.*ureg.m>>>s.radius=4.*ureg.cm>>>s.radius=4.*ureg.s...ValueError:radiusshouldbeinunitsconvertibletometerquantities Quantity exampleFinally, the following example shows how to restrict theradiusproperty to be aquantitiesquantity in units of length:importquantitiesaspqclassSphere(object):radius=NumericalProperty('radius',convertible_to=pq.m)will then behave as follows:>>>s=Sphere()>>>s.radius=3.*pq.m>>>s.radius=4.*pq.cm>>>s.radius=4.*pq.s...ValueError:radiusshouldbeinunitsconvertibletomPlanned supportLinking of properties (e.g. a property should have the same
dimensions as another)