Skip to content

Instantly share code, notes, and snippets.

@encukou
Last active August 29, 2015 13:57
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save encukou/9789993 to your computer and use it in GitHub Desktop.
Save encukou/9789993 to your computer and use it in GitHub Desktop.
Unpacking property example
from weakref import WeakKeyDictionary
class TupleProperty:
def __init__(self, *default_value):
self.values = WeakKeyDictionary()
self.length = len(default_value)
self.default_value = default_value
def __get__(self, obj, cls=None):
if obj:
return self.values.get(obj, self.default_value)
else:
return self
def __set__(self, obj, value):
assert len(value) == self.length
self.values[obj] = tuple(value)
def __iter__(self):
for i in range(self.length):
yield ComponentProperty(self, i)
class ComponentProperty:
def __init__(self, parent, index):
self.parent = parent
self.index = index
def __get__(self, obj, cls=None):
if obj:
return self.parent.__get__(obj)[self.index]
else:
return self
def __set__(self, obj, value):
prev = self.parent.__get__(obj)
new_tuple = prev[:self.index] + (value, ) + prev[self.index + 1:]
self.parent.__set__(obj, new_tuple)
def test_prop():
class SomeObject:
position = x, y, z = TupleProperty(0, 0, 0)
obj = SomeObject()
assert obj.position == (0, 0, 0)
assert obj.x == obj.y == obj.z == 0
obj.x = 1
assert obj.position == (1, 0, 0)
obj.y = 2
assert obj.position == (1, 2, 0)
obj.position = 4, 5, 6
assert obj.x == 4
assert obj.y == 5
assert obj.z == 6
if __name__ == '__main__':
test_prop()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment