📜 ⬆️ ⬇️

Another Enums implementation for Python

Last year, the Python community finally agreed to implement enums. The corresponding PEP 435 offer was developed, its implementation is already in python 3.4.

Watching the hot disputes, I decided to make my own bicycle as an experiment, adding a few features to it, the appearance of which in the official implementation was unlikely.

At the moment, the experiments have been completed, the library has shown itself well in my projects, so I decided to share it with the community.

In most cases, when we describe a relationship like <name, value>, we have a lot of information that we want to bind to the name: auxiliary text for the user interface, links to related enums, links to other objects or functions. It is necessary to fence additional data structures, which is not good - unnecessary entities, after all.
')
Therefore, inspired by the relational data model, I decided to abandon the implementation of enumerations in the form of binary relations and extend them to a full table.

At the same time added:


The result was such a thing (examples decided not to split up so as not to increase the already so long “canvas”):

######################## #   ######################## from rels import Column, Relation # Enum  EnumWithText     #    rels.Enum  rels.EnumWithText #        class Enum(Relation): #    name = Column(primary=True) #    value = Column(external=True) #    #  —     -  # ,      class EnumWithText(Enum): text = Column() class SOME_CONSTANTS(Enum): #    records = ( ('NAME_1', 1), #      ('NAME_2', 2)) class SOME_CONSTANTS_WITH_TEXT(EnumWithText): #     records = ( ('NAME_1', 1, 'constant 1'), ('NAME_2', 2, 'constant 2')) #    #    SOME_CONSTANTS.NAME_1.name == 'NAME_1' # True SOME_CONSTANTS.NAME_1.value == 1 # True #     «»  SOME_CONSTANTS(1) == SOME_CONSTANTS.NAME_1 # True #  SOME_CONSTANTS.NAME_2 == SOME_CONSTANTS.NAME_2 # True SOME_CONSTANTS.NAME_2 != SOME_CONSTANTS.NAME_1 # True #          SOME_CONSTANTS.NAME_2.is_NAME_1 # False SOME_CONSTANTS.NAME_2.is_NAME_2 # True #    —  , #          SOME_CONSTANTS.NAME_2 != SOME_CONSTANTS_WITH_TEXT.NAME_2 # True SOME_CONSTANTS.NAME_1 != SOME_CONSTANTS_WITH_TEXT.NAME_1 # True #  —    class EXTENDED_CONSTANTS(SOME_CONSTANTS_WITH_TEXT): #      records = ( ('NAME_3', 3, 'constant 3'), ) #     ######################## #  ######################## class ENUM(Relation): name = Column(primary=True) #       .index_name value = Column(external=True) #       .index_value text = Column(unique=False, index_name='by_key') #      records = ( ('NAME_1', 0, 'key_1'), ('NAME_2', 1, 'key_2'), ('NAME_3', 2, 'key_2'), ) #     ,       ENUM.index_name # {'NAME_1': ENUM.NAME_1, 'NAME_2': ENUM.NAME_2, 'NAME_3': ENUM.NAME_3} #      ,        ENUM.by_key # {'key_1': [ENUM.NAME_1], 'key_2': [ENUM.NAME_2, ENUM.NAME_3]} ######################## #   ######################## #  ,     class DESTINATION_ENUM(Relation): name = Column(primary=True) val = Column() records = ( ('STATE_1', 'value_1'), ('STATE_2', 'value_2') ) #  ,    class SOURCE_ENUM(Relation): name = Column(primary=True) val = Column() rel = Column(related_name='rel_source') records = ( ('STATE_1', 'value_1', DESTINATION_ENUM.STATE_1), ('STATE_2', 'value_2', DESTINATION_ENUM.STATE_2) ) #    DESTINATION_ENUM.STATE_1.rel_source == SOURCE_ENUM.STATE_1 # True DESTINATION_ENUM.STATE_2 == SOURCE_ENUM.STATE_2.rel # True 

Separately, I note that it is not necessary to declare listings in code. In many cases, it is more convenient to limit the declaration of the data model, and to load the data from third-party sources, for example, spreadsheets.

Repository and detailed documentation on github

PS library was developed in the calculation for Python 2.7, with the third one not tested.

Source: https://habr.com/ru/post/208066/


All Articles