Last active
June 3, 2023 11:54
-
-
Save ra101/aa27ff6e437f74ca56027a8c6b166882 to your computer and use it in GitHub Desktop.
A different implementation of constant for python
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
""" | |
constant.py: A different implementation of constant for python | |
""" | |
class ConstantMeta(type): | |
""" | |
Meta Class for Constant, How Constant class would behave | |
""" | |
def __new__(cls, clsname, bases, clsdict): | |
""" | |
adding __keys__, __values__ fields | |
and keys(), values() methods | |
""" | |
obj = super().__new__(cls, clsname, bases, clsdict) | |
obj.__force_set__("__values__", []) | |
obj.__force_set__("__keys__", []) | |
for key, val in vars(obj).items(): | |
if not key.startswith("__"): | |
obj.__values__.append(val) | |
obj.__keys__.append(key) | |
obj.__force_set__("keys", lambda: obj.__keys__) | |
obj.__force_set__("values", lambda: obj.__values__) | |
return obj | |
def __force_set__(self, name, value): | |
# A external set method to make sure we can update value in __new__ | |
return super().__setattr__(name, value) | |
def __setattribute__(self, *args, **kwargs): | |
# Override set method to make it immutable | |
# raise ValueError('Updating Immutable Type') | |
pass | |
def __setattr__(self, *args, **kwargs): | |
# Override set method to make it immutable | |
# raise ValueError('Updating Immutable Type') | |
pass | |
def __setitem__(self, *args, **kwargs): | |
# Override set method to make it immutable | |
# raise ValueError('Updating Immutable Type') | |
pass | |
def __set__(self, *args, **kwargs): | |
# Override set method to make it immutable | |
# raise ValueError('Updating Immutable Type') | |
pass | |
def __getitem__(cls, key): | |
# adding __getitem__ to make objects "subscriptable" | |
return getattr(cls, key) | |
def __iter__(cls): | |
# In case of for loops | |
return zip(cls.__keys__, cls.__values__) | |
class ConstantClass(metaclass=ConstantMeta): | |
""" | |
Now this class can be inhereted whenever required to make constants | |
""" | |
pass | |
if __name__ == "__main__": | |
""" | |
An Example of how this works | |
""" | |
class Links(ConstantClass): | |
GITHUB = "https://github.com/ra101" | |
WEB = "https://ra101.github.io/" | |
LINKS = "dev.ra.101@protonmail.com" | |
class Author(ConstantClass): | |
NAME = "〈 RA 〉" | |
WEB = Links.WEB | |
LINKS = Links | |
Links.WEB = 'any_new_value' | |
print(f"\nLinks.WEB: {Links.WEB}") | |
print(f"\nAuthor.values(): {Author.values()}") | |
print(f"\ndict(Author): {dict(Author)}") | |
print("\nfor key in Author.LINKS.keys()") | |
for key in Author.LINKS.keys(): | |
print(f'getattr(Author.LINKS, "{key}"): {getattr(Author.LINKS, key)}') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Output: