Skip to content

Instantly share code, notes, and snippets.

@eevee
Created November 11, 2016 22:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eevee/d75cf9367e3346d8fb0099f047b523e5 to your computer and use it in GitHub Desktop.
Save eevee/d75cf9367e3346d8fb0099f047b523e5 to your computer and use it in GitHub Desktop.
intercepting attribute assignment
class InterceptableAttribute:
def __init__(self, name, *twiddles):
self.twiddles = twiddles
# NOTE: this call and the 'name' arg will no longer be necessary in
# Python 3.6
self.__set_name__(None, name)
def __set_name__(self, owner, name):
self.name = name
def __get__(self, instance, owner):
if instance is None:
return self
return instance.__dict__[self.name]
def __set__(self, instance, value):
if self.name in instance.__dict__:
old_value = instance.__dict__[self.name]
for twiddle in self.twiddles:
value = twiddle(old_value, value)
instance.__dict__[self.name] = value
class SomeClass:
can_only_shrink = InterceptableAttribute('can_only_shrink', min)
can_only_grow = InterceptableAttribute('can_only_grow', max)
def __init__(self, start):
self.can_only_shrink = start
self.can_only_grow = start
foo = SomeClass(5)
print(foo.can_only_shrink, foo.can_only_grow) # 5, 5
foo.can_only_shrink += 20
foo.can_only_grow -= 20
print(foo.can_only_shrink, foo.can_only_grow) # 5, 5
foo.can_only_shrink -= 20
foo.can_only_grow += 20
print(foo.can_only_shrink, foo.can_only_grow) # -15, 25
foo.can_only_shrink += 20
foo.can_only_grow -= 20
print(foo.can_only_shrink, foo.can_only_grow) # -15, 25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment