Skip to content

Instantly share code, notes, and snippets.

@ychennay
Last active March 21, 2020 23:05
Show Gist options
  • Save ychennay/88c44f8b69deac24f4b2360ec545351e to your computer and use it in GitHub Desktop.
Save ychennay/88c44f8b69deac24f4b2360ec545351e to your computer and use it in GitHub Desktop.
from weakref import WeakKeyDictionary
class NonNullStringDescriptor:
CAPACITY = 2 # maximum of two instances can store their non-default attribute values here
def __init__(self, value: str = "Default Name"):
self._instance_values = WeakKeyDictionary()
self.__default = value
def __get__(self, instance, owner):
"""
Instead of directly returning the value directory, we look up each instance's value using the instance itself
as the key.
"""
if len(self._instance_values) < NonNullStringDescriptor.CAPACITY:
self._instance_values[instance] = self.__default
return self._instance_values.get(instance, self.__default)
def __set__(self, instance, value):
if instance not in self._instance_values and len(self._instance_values) >= NonNullStringDescriptor.CAPACITY:
# if we are trying to add a new instance to descriptor instance store
raise AttributeError("We've reached the maximum number of allowed instances.")
elif instance in self._instance_values and value == self.__default:
# if we are setting the instance value back to the default value, remove it from the weak ref dict
self._instance_values.pop(instance)
return self.__default
# perform validation of value being set
if isinstance(value, str) and len(value.strip()) > 0:
self._instance_values[instance] = value
else:
raise TypeError("The value provided is not a non-null string.")
if __name__ == "__main__":
student = Person()
studentB = Person()
studentC = Person()
print(student.name) # Default Name
print(studentB.name) # Default Name
studentB.name = "Padma"
print(studentB.name) # "Padma"
print(student.name) # Default Name
student.name = "Yu"
print(student.name) # Yu
print(studentC.name) # Default Name
studentC.name = "Vlad" # AttributeError: We've reached the maximum number of allowed instances.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment