propertytools¶
This module implements property
like classes with similar or
additional behaviour.
Module propertytools
implements the following members:
DefaultPropertyStr
The central part of internal API.
InputType
Type variable.
InputType_contra
Type variable.
OutputType
Type variable.
OutputType_co
Type variable.
ProtectedPropertyStr
The central part of internal API.
BaseDescriptor
Base class for defining descriptors.
FGet
Callback protocol for getter functions.
FSet
Callback protocol for setter functions.
FDel
Callback protocol for deleter functions.
BaseProperty
Abstract base class for deriving classes similar toproperty
.
Property
ClassProperty
mimics the behaviour of the built-in functionproperty
.
ProtectedProperty
Aproperty
-like class which prevents getting an attribute before setting it.
ProtectedProperties
Iterable forProtectedProperty
objects.
DependentProperty
property
-like class which prevents accessing a dependent attribute before preparing certain other attributes.
DefaultProperty
property
-like class which uses the getter function to return a default value unless a custom value is available.
-
class
hydpy.core.propertytools.
BaseDescriptor
[source]¶ Bases:
object
Base class for defining descriptors.
-
objtype
: Type[Any]¶
-
-
class
hydpy.core.propertytools.
FGet
(*args, **kwds)[source]¶ Bases:
typing_extensions.Protocol
[hydpy.core.propertytools.OutputType_co
]Callback protocol for getter functions.
-
class
hydpy.core.propertytools.
FSet
(*args, **kwds)[source]¶ Bases:
typing_extensions.Protocol
[hydpy.core.propertytools.InputType_contra
]Callback protocol for setter functions.
-
class
hydpy.core.propertytools.
FDel
(*args, **kwds)[source]¶ Bases:
typing_extensions.Protocol
Callback protocol for deleter functions.
-
class
hydpy.core.propertytools.
BaseProperty
(*args, **kwds)[source]¶ Bases:
Generic
[hydpy.core.propertytools.InputType
,hydpy.core.propertytools.OutputType
],hydpy.core.propertytools.BaseDescriptor
Abstract base class for deriving classes similar to
property
.BaseProperty
provides the abstract methodscall_fget()
,call_fset()
, andcall_fdel()
, which are the appropriate places to add custom functionalities (e.g. caching). See subclassProperty
for an example, which mimics the behaviour of the built-inproperty
function.BaseProperty
property uses dummy getter, setter and deleter functions to indicate than at an actual getter, setter or deleter function is missing. In case they are called due to the wrong implementation of aBaseProperty
subclass, they raise aRuntimeError
:>>> from hydpy.core.propertytools import BaseProperty >>> BaseProperty._fgetdummy(None) Traceback (most recent call last): ... RuntimeError
>>> BaseProperty._fsetdummy(None, None) Traceback (most recent call last): ... RuntimeError
>>> BaseProperty._fdeldummy(None) Traceback (most recent call last): ... RuntimeError
-
fget
: hydpy.core.propertytools.FGet[OutputType]¶
-
fset
: hydpy.core.propertytools.FSet[InputType]¶
-
abstract
call_fget
(obj: Any) → OutputType[source]¶ Method for implementing unique getter functionalities.
-
-
class
hydpy.core.propertytools.
Property
(fget: hydpy.core.propertytools.FGet[OutputType] = <function BaseProperty._fgetdummy>, fset: hydpy.core.propertytools.FSet[InputType] = <function BaseProperty._fsetdummy>, fdel: hydpy.core.propertytools.FDel = <function BaseProperty._fdeldummy>)[source]¶ Bases:
hydpy.core.propertytools.BaseProperty
[hydpy.core.propertytools.InputType
,hydpy.core.propertytools.OutputType
]Class
Property
mimics the behaviour of the built-in functionproperty
.The only advantage of
Property
overproperty
is that it allows defining different input and output types statically. If the input and output types are identical, preferproperty
, which is probably faster.The following test class implements its attribute x by defining all three “property methods” (getter/fget, setter/fset, deleter/fdel), but its attribute y by defining none of them:
>>> from hydpy.core.propertytools import Property >>> class Test: ... ... def __init__(self): ... self._x = None ... self._y = None ... ... @Property ... def x(self): ... return self._x ... @x.setter ... def x(self, value): ... self._x = value ... @x.deleter ... def x(self): ... self._x = None ... ... y = Property()
After initialising a test object, you can use its attribute x as expected:
>>> test = Test() >>> test.x >>> test.x = 2 >>> test.x 2 >>> del test.x >>> test.x
When trying to invoke attribute y, you get the following error messages:
>>> test.y Traceback (most recent call last): ... AttributeError: Attribute `y` of object `test` is not gettable.
>>> test.y = 1 Traceback (most recent call last): ... AttributeError: Attribute `y` of object `test` is not settable.
>>> del test.y Traceback (most recent call last): ... AttributeError: Attribute `y` of object `test` is not deletable.
-
fget
: hydpy.core.propertytools.FGet[OutputType]¶
-
fset
: hydpy.core.propertytools.FSet[InputType]¶
-
getter
(fget: hydpy.core.propertytools.FGet[OutputType]) → hydpy.core.propertytools.Property[InputType, OutputType][source]¶ Add the given getter function and its docstring to the property and return it.
-
setter
(fset: hydpy.core.propertytools.FSet[InputType]) → hydpy.core.propertytools.Property[InputType, OutputType][source]¶ Add the given setter function to the property and return it.
-
deleter
(fdel: hydpy.core.propertytools.FDel) → hydpy.core.propertytools.Property[InputType, OutputType][source]¶ Add the given deleter function to the property and return it.
-
objtype
: Type[Any]¶
-
-
class
hydpy.core.propertytools.
ProtectedProperty
(fget: hydpy.core.propertytools.FGet[OutputType] = <function BaseProperty._fgetdummy>, fset: hydpy.core.propertytools.FSet[InputType] = <function BaseProperty._fsetdummy>, fdel: hydpy.core.propertytools.FDel = <function BaseProperty._fdeldummy>)[source]¶ Bases:
hydpy.core.propertytools.BaseProperty
[hydpy.core.propertytools.InputType
,hydpy.core.propertytools.OutputType
]A
property
-like class which prevents getting an attribute before setting it.Some attributes need preparations before being accessible. Consider the case where a property of a Python class (being part of the API) links to an attribute of a Cython extension class (not part of the API). If the Cython attribute is, for example, a vector requiring memory allocation, trying to query this vector before it has been initialised results in a program crash. Using
ProtectedProperty
is a means to prevent such problems.The following class Test defines most simple getter, setter, and deleter functions for its only property x:
>>> from hydpy.core.propertytools import ProtectedProperty >>> class Test: ... ... def __init__(self): ... self._x = None ... ... x = ProtectedProperty() ... @x.getter ... def x(self): ... "Test" ... return self._x ... @x.setter ... def x(self, value): ... self._x = value ... @x.deleter ... def x(self): ... self._x = None
Trying to query x directly after initialising a Test object results in an
AttributeNotReady
error:>>> test = Test() >>> test.x Traceback (most recent call last): ... hydpy.core.exceptiontools.AttributeNotReady: Attribute `x` of object `test` has not been prepared so far.
After setting a value, you can query this value as expected:
>>> test.x = 1 >>> test.x 1
After deleting the value, the protection mechanism applies again:
>>> del test.x >>> test.x Traceback (most recent call last): ... hydpy.core.exceptiontools.AttributeNotReady: Attribute `x` of object `test` has not been prepared so far.
-
fget
: hydpy.core.propertytools.FGet[OutputType]¶
-
fset
: hydpy.core.propertytools.FSet[InputType]¶
-
call_fget
(obj: Any) → OutputType[source]¶ When ready, call fget; otherwise, raise an
AttributeNotReady
exception.
-
isready
(obj: Any) → bool[source]¶ Return
True
orFalse
to indicate if the protected property is ready for the given object. If the object is unknown,isready()
returnsFalse
.
-
getter
(fget: hydpy.core.propertytools.FGet[OutputType]) → hydpy.core.propertytools.ProtectedProperty[InputType, OutputType][source]¶ Add the given getter function and its docstring to the property and return it.
-
setter
(fset: hydpy.core.propertytools.FSet[InputType]) → hydpy.core.propertytools.ProtectedProperty[InputType, OutputType][source]¶ Add the given setter function to the property and return it.
-
deleter
(fdel: hydpy.core.propertytools.FDel) → hydpy.core.propertytools.ProtectedProperty[InputType, OutputType][source]¶ Add the given deleter function to the property and return it.
-
objtype
: Type[Any]¶
-
-
hydpy.core.propertytools.
ProtectedPropertyStr
¶ ProtectedProperty
for handlingstr
objects.alias of hydpy.core.propertytools.ProtectedProperty[str, str]
-
class
hydpy.core.propertytools.
ProtectedProperties
(*properties: hydpy.core.propertytools.ProtectedProperty[Any, Any])[source]¶ Bases:
object
Iterable for
ProtectedProperty
objects.You can collect an arbitrary number of
ProtectedProperty
objects within aProtectedProperties
object. Itsallready()
method allows checking the status of all properties at ones:>>> from hydpy.core import propertytools as pt >>> class Test: ... ... @pt.ProtectedProperty ... def x(self): ... return "this is x" ... @x.setter ... def x(self, value): ... pass ... ... @pt.ProtectedProperty ... def z(self): ... return "this is z" ... @z.setter ... def z(self, value): ... pass ... ... protectedproperties = pt.ProtectedProperties(x, z)
>>> test1 = Test() >>> test1.x = None >>> test2 = Test() >>> test2.x = None >>> test2.z = None >>> Test.protectedproperties.allready(test1) False >>> Test.protectedproperties.allready(test2) True
-
class
hydpy.core.propertytools.
DependentProperty
(protected: Tuple[hydpy.core.propertytools.ProtectedProperty[Any, Any], ...], fget: hydpy.core.propertytools.FGet[OutputType] = <function BaseProperty._fgetdummy>, fset: hydpy.core.propertytools.FSet[InputType] = <function BaseProperty._fsetdummy>, fdel: hydpy.core.propertytools.FDel = <function BaseProperty._fdeldummy>)[source]¶ Bases:
hydpy.core.propertytools.BaseProperty
[hydpy.core.propertytools.InputType
,hydpy.core.propertytools.OutputType
]property
-like class which prevents accessing a dependent attribute before preparing certain other attributes.Please read the documentation on class
ProtectedProperty
, from which we take the following example. x is a simpleProtectedProperty
again, but time we add theDependentProperty
y:>>> from hydpy.core import propertytools as pt >>> class Test: ... ... def __init__(self): ... self._x = None ... self._y = None ... ... @pt.ProtectedProperty ... def x(self): ... return self._x ... @x.setter ... def x(self, value): ... self._x = value ... @x.deleter ... def x(self): ... self._x = None ... ... y = pt.DependentProperty(protected=(x,)) ... ... @y.getter ... def y(self): ... return self._y ... @y.setter ... def y(self, value): ... self._y = value ... @y.deleter ... def y(self): ... self._y = None
Initially, due to x not being prepared, there is no way to get, set, or delete attribute y:
>>> test = Test() >>> test.y Traceback (most recent call last): ... hydpy.core.exceptiontools.AttributeNotReady: Attribute `y` of object `test` is not usable so far. At least, you have to prepare attribute `x` first. >>> test.y = 1 Traceback (most recent call last): ... hydpy.core.exceptiontools.AttributeNotReady: Attribute `y` of object `test` is not usable so far. At least, you have to prepare attribute `x` first. >>> del test.y Traceback (most recent call last): ... hydpy.core.exceptiontools.AttributeNotReady: Attribute `y` of object `test` is not usable so far. At least, you have to prepare attribute `x` first.
After assigning a value to x, y behaves like a common property:
>>> test.x = "anything" >>> test.y = 1 >>> test.y 1 >>> del test.y >>> test.y
-
protected
: Tuple[hydpy.core.propertytools.ProtectedProperty[Any, Any], …]¶
-
call_fget
(obj: Any) → OutputType[source]¶ Call fget when all required attributes are ready; otherwise, raise an
AttributeNotReady
error.
-
call_fset
(obj: Any, value: InputType) → None[source]¶ Call fset when all required attributes are ready; otherwise, raise an
AttributeNotReady
error.
-
call_fdel
(obj: Any) → None[source]¶ Call fdel when all required attributes are ready; otherwise, raise an
AttributeNotReady
error.
-
getter
(fget: hydpy.core.propertytools.FGet[OutputType]) → hydpy.core.propertytools.DependentProperty[InputType, OutputType][source]¶ Add the given getter function and its docstring to the property and return it.
-
setter
(fset: hydpy.core.propertytools.FSet[InputType]) → hydpy.core.propertytools.DependentProperty[InputType, OutputType][source]¶ Add the given setter function to the property and return it.
-
deleter
(fdel: hydpy.core.propertytools.FDel) → hydpy.core.propertytools.DependentProperty[InputType, OutputType][source]¶ Add the given deleter function to the property and return it.
-
-
class
hydpy.core.propertytools.
DefaultProperty
(fget: hydpy.core.propertytools.FGet[OutputType] = <function BaseProperty._fgetdummy>)[source]¶ Bases:
hydpy.core.propertytools.BaseProperty
[hydpy.core.propertytools.InputType
,hydpy.core.propertytools.OutputType
]property
-like class which uses the getter function to return a default value unless a custom value is available.In the following example, the default value of property x is one:
>>> from hydpy.core.propertytools import DefaultProperty >>> class Test: ... ... @DefaultProperty ... def x(self): ... "Default property x." ... return 1
Initially, property x returns the default value defined by its getter function:
>>> test = Test() >>> test.x 1
Assigned custom values override such default values:
>>> test.x = 3 >>> test.x 3
After removing the custom value, it is again up to the getter function to return the default value:
>>> del test.x >>> test.x 1
Trying to delete a not existing custom value does not harm:
>>> del test.x
The documentation string of the getter functions serves as the documentation string of the default property:
>>> Test.x.__doc__ 'Default property x.'
-
fget
: hydpy.core.propertytools.FGet[OutputType]¶
-
fset
: hydpy.core.propertytools.FSet[InputType]¶
-
call_fget
(obj: Any) → OutputType[source]¶ If available, return the predefined custom value; otherwise, return the value defined by the getter function.
-
objtype
: Type[Any]¶
-
-
hydpy.core.propertytools.
DefaultPropertyStr
¶ DefaultProperty
for handlingstr
objects.alias of hydpy.core.propertytools.DefaultProperty[str, str]