Python: Reimaging Constants

A different implementation of constant for python

I couldn’t find a good implementation of constants, so created my own! Let’s get started!

Do checkout the complete code at https://gist.github.com/ra101/aa27ff6e437f74ca56027a8c6b166882

How it Should…


This content originally appeared on DEV Community and was authored by Parth Agarwal

A different implementation of constant for python

I couldn't find a good implementation of constants, so created my own! Let's get started!

Do checkout the complete code at https://gist.github.com/ra101/aa27ff6e437f74ca56027a8c6b166882

How it Should work

    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

Now Links.GITHUB should return https://github.com/ra101 and
Link.GITHUB = 'new_value' or Links.NEW_CONTANTS = NEW_VALUE both should return None, without assigning or creating new field

Here is How I made it!

1) We need to mock all setter in a meta class, which will be used by main class.

class ConstantMeta(type):
    """
    Meta Class for Constant, How Constant class would behave
    """

    def __setattribute__(self, *args, **kwargs):
        # Override set method to make it immutable
        pass

    def __setattr__(self, *args, **kwargs):
        # Override set method to make it immutable
        pass

    def __setitem__(self, *args, **kwargs):
        # Override set method to make it immutable
        pass

    def __set__(self, *args, **kwargs):
        # Override set method to make it immutable
        pass

1.5) Lets add a external setter

    def __force_set__(self, name, value):
        # A external set method to make sure we can update value in __new__
        return super().__setattr__(name, value)

2) Override __new__ to make the actual class

    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

2.5) Add below methods for polishing the class


    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__)

3) Finally Lets create the class!


class ConstantClass(metaclass=ConstantMeta):
    """
    Now this class can be inherited whenever required to make constants
    """

    pass

Finally! We are Done! We Created a almost immutable class that could be used as constants

Examples

Input:

    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)}')



Output:

Links.WEB: https://ra101.github.io/

Author.values(): ['〈 RA 〉', 'https://ra101.github.io/', <__main__.ConstantClass object at 0x00000293A94768E0>]

dict(Author): {'NAME': '〈 RA 〉', 'WEB': 'https://ra101.github.io/', 'LINKS': <__main__.ConstantClass object at 0x00000293A94768E0>}

for key in Author.LINKS.keys()
getattr(Author.LINKS, "GITHUB"): https://github.com/ra101
getattr(Author.LINKS, "WEB"): https://ra101.github.io/
getattr(Author.LINKS, "EMAIL"): dev.ra.101@protonmail.com

Do checkout the complete code at https://gist.github.com/ra101/aa27ff6e437f74ca56027a8c6b166882


This content originally appeared on DEV Community and was authored by Parth Agarwal


Print Share Comment Cite Upload Translate Updates
APA

Parth Agarwal | Sciencx (2021-10-02T18:58:26+00:00) Python: Reimaging Constants. Retrieved from https://www.scien.cx/2021/10/02/python-reimaging-constants/

MLA
" » Python: Reimaging Constants." Parth Agarwal | Sciencx - Saturday October 2, 2021, https://www.scien.cx/2021/10/02/python-reimaging-constants/
HARVARD
Parth Agarwal | Sciencx Saturday October 2, 2021 » Python: Reimaging Constants., viewed ,<https://www.scien.cx/2021/10/02/python-reimaging-constants/>
VANCOUVER
Parth Agarwal | Sciencx - » Python: Reimaging Constants. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2021/10/02/python-reimaging-constants/
CHICAGO
" » Python: Reimaging Constants." Parth Agarwal | Sciencx - Accessed . https://www.scien.cx/2021/10/02/python-reimaging-constants/
IEEE
" » Python: Reimaging Constants." Parth Agarwal | Sciencx [Online]. Available: https://www.scien.cx/2021/10/02/python-reimaging-constants/. [Accessed: ]
rf:citation
» Python: Reimaging Constants | Parth Agarwal | Sciencx | https://www.scien.cx/2021/10/02/python-reimaging-constants/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.