This library allows you to link properties, so if one is changed the others change accordingly.
This is a python library that allows you to link properties together, so if one is changed the others change accordingly.
You can use this library everywhere, I don’t care. Giving credit would be nice, but is optional.
$ pip install linked_properties
The library consists of two important parts: WatchableProperty and LinkableProperty.
A class named ComplexLinkedProperty or something like that may be added in the future, it would combine both concepts; but it would need additional work. I added the documentation anyways.
As the docstring states:
WatchableProperty is a class that is used to create a property that can be submitted to a LinkableProperty. It works exactly the same as "property", except for the name. If a linked property is reading from another one, than this object may be blocked for writing for the instance in question. To get around this, you may define an "at_blocked_set" function, that unlocks the linked property by setting it to None. It may return true or false, if it is true, the __set__ function is called another time. Note: the at_blocked_set function can invoke the __set__ function again only once per tried write access!
You cannot use normal properties to make LinkableProperties work.
Here’s how you can use them (Spoiler Alert: It’s (almost) exactly the same as with the builtin properties): * 1st option: Replace the builtin property (kind of). This should generally not be used, although it can be used if you are updating an old project to fit the requirements automatically.
import linked_properties property = linked_properties.WatchableProperty # ... (Your own code)
2nd option: Using them with function decorators. This should be the preferred way, but some (or just this one, i don’t know) editors like PyCharm think you are working with the builtin properties. This may lead to warnings that shouldn’t exist.
import linked_properties # ... (Your own code) class SomeName(object): # ... (Your own code) @linked_properties.WatchableProperty def x(self) -> int: return self._x @x.setter def x(self, value: int) -> None: self._x = int(value) # ... (Your own code) # ... (Your own code)
3rd option: Using them the ugly way. This is still better than the first one, and it’s the only one to make PyCharm stop spawning warnings because of types all over the place.
import linked_properties # ... (Your own code) class SomeName(object): # ... (Your own code) # ... (Your own code) def _get_x(self) -> int: return self._x def _set_x(self, value: int) -> None: self._x = value x = linked_properties.WatchableProperty(_get_x, _set_x) # ... (Your own code) # ... (Your own code)
But be aware of this: Two things is different.
While @property_name.setter returns a new instance for a builtin property because they are immutable, a WatchableProperty returns itself and changes accordingly because it is mutable.
Just try to avoid situations where you need mutable or immutable descriptors, because this behaviour can change in future versions. (I can’t even think of a situation where this would help)
And you cannot define a deleter, although that may change in the future as well.
I personally can learn better from examples. So here is one:
import linked_properties class Widget(object): def __init__(self, width: int, height: int) -> None: self._width = 0 # type: int self._height = 0 # type: int self.width = width self.height = height @linked_property.WatchableProperty def width(self) -> int: return self._width @width.setter def width(self, new_value: int) -> None: assert isinstance(new_value, int) self._width = new_value l_width = linked_properties.LinkableProperty(width) # ... (height; see width)
Or after the ComplexLinkableProperty arrived:
import linked_properties class Widget(object): def __init__(self, width: int, height: int) - None: self._width = 0 # type: int self._height = 0 # type: int self.width = width self.height = height @linked_property.ComplexLinkableProperty def width(self) -> int: return self._width @width.setter def width(self, new_value: int) -> None: assert isinstance(new_value, int) self._width = new_value
If you want to contribute, just email me: email@example.com
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Hashes for linked_properties-1.0.0b1-py2.py3-none-any.whl