Skip to content

Instantly share code, notes, and snippets.

@averrin
Created May 24, 2013 12:51
Show Gist options
  • Save averrin/5643293 to your computer and use it in GitHub Desktop.
Save averrin/5643293 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import print_function
from functools import partial
import random
__author__ = 'Alexey "Averrin" Nabrodov'
__version__ = '0.0.0'
def addBinding(obj1, prop1, obj2, prop2, one_way=False):
class WProperty(object):
def __init__(self, name):
self.name = name
self.owner = None
self.onSet = []
def __get__(self, obj, objtype=None):
return getattr(obj, "__" + self.name, None)
def __set__(self, obj, value):
setattr(obj, "__" + self.name, value)
self.owner = obj
for handler in self.onSet:
handler(obj, value)
def addHandler(self, handler):
self.onSet.append(handler)
def addBinding(self, prop, one_way=False):
prop.addHandler(lambda o, x: setattr(self.owner, "__" + self.name, x))
if not one_way:
self.addHandler(lambda o, x: setattr(prop.owner, "__" + self.name, x))
val1 = getattr(obj1, prop1)
p1 = WProperty(prop1)
rp1 = prop1 + str(random.randint(0,9999))
obj1.__props[prop1] = rp1
setattr(type(obj1), rp1, p1)
setattr(obj1, prop1 + "Property", p1)
p1.__set__(obj1, val1)
val2 = getattr(obj2, prop2)
p2 = WProperty(prop2)
rp2 = prop2 + str(random.randint(0,9999))
obj2.__props[prop2] = rp2
setattr(type(obj2), rp2, p2)
setattr(obj2, prop2 + "Property", p2)
p2.__set__(obj2, val2)
p1.addBinding(p2, one_way)
class SadObject(object):
def __getattribute__(self, key):
props = object.__getattribute__(self, "__props")
if key in props:
key = props[key]
pv = type(self).__dict__[key].__get__(self, key)
return pv
return object.__getattribute__(self, key)
def __setattr__(self, key, value):
if not hasattr(self, "__props"):
object.__setattr__(self, "__props", {})
if key in object.__getattribute__(self, "__props"):
key = object.__getattribute__(self, "__props")[key]
type(self).__dict__[key].__set__(self, value)
else:
object.__setattr__(self, key, value)
def main():
class A(SadObject): pass
class B(SadObject): pass
obj = A()
obj2 = B()
obj3 = B()
obj.a = "a"
obj2.a = "b"
obj3.a = "z"
print(obj.a, obj2.a, obj3.a)
addBinding(obj, "a", obj2, "a")
print(obj.a, obj2.a, obj3.a)
obj.a = "c"
print(obj.a, obj2.a, obj3.a)
obj2.a = "d"
print(obj.a, obj2.a, obj3.a)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment