Created
September 26, 2023 06:53
-
-
Save nenetto/33af21a96db58ba667a69ec4040feef3 to your computer and use it in GitHub Desktop.
Mix-in Classes
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
# Avoid using multiple inheritance if mix-in classes can achieve the same outcome. | |
# Use pluggable behaviors at the instance level to provide per-class customization when mix-in classes may require it. | |
# Compose mix-ins to create complex functionality from simple behaviors. | |
class ToDictMixin(object): | |
"""This class add the ability to serialize an object to a dictionary | |
Takes each element of self.__dict__ and saves it | |
""" | |
def to_dict(self): | |
return self._traverse_dict(self.__dict__) | |
def _traverse_dict(self, instance_dict): | |
output = {} | |
for key, value in instance_dict.items(): | |
output[key] = self._traverse(key, value) | |
return output | |
def _traverse(self, key, value): | |
# If the object's class has also the Mixin functionality, use the same method | |
if isinstance(value, ToDictMixin): | |
return value.to_dict() | |
# If the object is a dict instance, just copy | |
elif isinstance(value, dict): | |
return self._traverse_dict(value) | |
# If the object is a list instance, apply to each value | |
elif isinstance(value, list): | |
return [self._traverse(key, i) for i in value] | |
# If the object has the __dict__ memeber, parse that dictionary | |
elif hasattr(value, ‘__dict__’): | |
return self._traverse_dict(value.__dict__) | |
else: | |
return value | |
class JsonMixin(object): | |
"""This class serialize into a json and can be combined with previous Mixin""" | |
@classmethod | |
def from_json(cls, data): | |
kwargs = json.loads(data) | |
return cls(**kwargs) | |
def to_json(self): | |
return json.dumps(self.to_dict()) | |
class DatacenterRack(ToDictMixin, JsonMixin): | |
def __init__(self, switch=None, machines=None): | |
self.switch = Switch(**switch) | |
self.machines = [Machine(**kwargs) for kwargs in machines] | |
class Switch(ToDictMixin, JsonMixin): | |
#... | |
class Machine(ToDictMixin, JsonMixin): | |
#... | |
## Example of serialized switch | |
serialized = ”””{ | |
“switch”: {“ports”: 5, “speed”: 1e9}, | |
“machines”: [ | |
{“cores”: 8, “ram”: 32e9, “disk”: 5e12}, | |
{“cores”: 4, “ram”: 16e9, “disk”: 1e12}, | |
{“cores”: 2, “ram”: 4e9, “disk”: 500e9} | |
] | |
}””” | |
deserialized = DatacenterRack.from_json(serialized) | |
roundtrip = deserialized.to_json() | |
assert json.loads(serialized) == json.loads(roundtrip) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment