Created
September 20, 2020 11:57
-
-
Save revuel/f8e384adcd70054ddca21eb7beb021d4 to your computer and use it in GitHub Desktop.
Example of using slotting a POPO class overriding __setattr__ to do validations
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" Just playing around with slots (BASIC EXAMPLE Plain Old Python Object) """ | |
import re | |
date_pattern = re.compile(r'(\d{4})[/.-](\d{2})[/.-](\d{2})$') | |
class Person(object): | |
""" Person sample class with slots """ | |
__slots__ = ('name', 'dob') | |
def __init__(self): | |
print(f'Initializing instance of {self}') | |
@property | |
def __dict__(self): | |
""" Dictionary representation for a slotted class (that has no dict at all) """ | |
# Above works just for POPOs | |
return {s: getattr(self, s, None) for s in self.__slots__} | |
def __repr__(self): | |
""" String representation of a slotted class using hijacked dict """ | |
return f'{self.__class__.__name__}({self.__dict__})' | |
def __setattr__(self, key, value): | |
print(f'Setting attribute "{key}" of {self} instance with {value} value') | |
if key == 'dob' and not date_pattern.match(value): | |
raise ValueError(f'Invalid date format "{value}" for {key} attribute') | |
else: | |
# Above is the trick to override __setattr__ in a slotted class | |
super(Person, self).__setattr__(key, value) | |
if __name__ == '__main__': | |
print(f'Running...') | |
p1 = Person() | |
p2 = Person() | |
try: | |
p1.name = 'Michael' | |
p1.dob = '1988/03/22' | |
p2.name = 'Rachel' | |
# Above will crash since it does not match the pattern yyyy/mm/dd | |
p2.dob = 'this-is-not-a-valid-date-format' | |
except Exception as ex: | |
print(f'{ex} was raised') | |
finally: | |
print(f'Person one is {p1}, person two is {p2}') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment