Skip to content

Instantly share code, notes, and snippets.

@minstrel271
Last active March 11, 2016 08:36
Show Gist options
  • Save minstrel271/77b3e3d412651d61b3cb to your computer and use it in GitHub Desktop.
Save minstrel271/77b3e3d412651d61b3cb to your computer and use it in GitHub Desktop.
from functools import lru_cache
class AttributeManager(object):
"""
A base class of attribute manager.
The name of the attribute are scanned and saved from the owner classes.
The value of each instance are saved as __name
>>> class Apple(object):
... favor = AttributeManager()
>>> apple = Apple()
>>> apple.favor = 'sweet'
>>> apple.favor
'sweet'
>>> apple.__favor
'sweet'
"""
def __init__(self, format='__{}'):
self.format = format
def __get__(self, instance, owner):
"""
When refered by an instance, return the managed attribute.
Otherwise, return itself.
"""
if instance is None:
return self
name = self.name(owner)
return getattr(instance, name)
def __set__(self, instance, value):
"""
Set the managed attribute as the value given
"""
name = self.name(type(instance))
setattr(instance, name, value)
@lru_cache()
def name(self, owner):
"""
Scan the name of the managed attribute for the owner class.
The result are saved in lru_cache for future uses.
"""
for attr in dir(owner):
if getattr(owner, attr) is self:
return self.format.format(attr)
class const(object):
"""
A class constant manager where the managed content cannot be modified by instance.
For mutable attribute, a copy function can be provided for extra security.
>>> from copy import copy
>>> class Apple(object):
... favor = const('sweet')
... content = const(['water', 'sugar'], copy)
>>> apple = Apple()
>>> apple.favor
'sweet'
>>> apple.favor = 'sweet'
Traceback (most recent call last):
....
RuntimeError: Modifing constant attribute
>>> apple.content[0] = 'oil'
>>> apple.content
['water', 'sugar']
"""
def __init__(self, value, copy=None):
self.value = value
self.copy = copy
def __get__(self, instance, owner):
if self.copy is None:
return self.value
else:
return self.copy(self.value)
def __set__(self, instance, value):
raise RuntimeError('Modifing constant attribute')
class regulated(AttributeManager):
"""
A regulated attribute that check before setting its value.
Attributes:
regulate(self, value) (function): function that check/midify the value before saving
"""
def __init__(self, regulate, **kwargs):
super().__init__(**kwargs)
self.regulate = regulate
def __set__(self, instance, value):
super().__set__(instance, self.regulate(instance, value))
if __name__ == '__main__':
import doctest
doctest.testmod()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment