[Python] Using Enum values as type variables, without using Literal

Discussão em 'Python' iniciado por Stack, Julho 7, 2025.

  1. Stack

    Stack Membro Participativo

    I'm trying to represent physical dimensions (length, time, temperature, ...), and cannot find a nice way to do so, that is compatible with type hinting and generics.

    Ideally, I want to be able to define an Enum whose names are types themselves (a metaenum ?):

    from enum import Enum

    class Dim(Enum):
    TIME = "t"
    MASS = "m"


    I can type hint dimensions (dim: Dim) but cannot do things like

    from typing import Generic, TypeVar

    T = TypeVar("T", bound=Dim) # only accepts `Dim`

    class PhysicalQuantity(Generic[T]):
    pass

    class Container:
    some_time: PhysicalQuantity[Dim.TIME] # doesn't work


    because these are values.

    Is there a construct as simple as Enum, but to make types instead of values ?

    Reasons why I want to keep Enum:

    • very easy to define
    • very easy to associate to a value (str)
    • Ability to sort of "think of Dim as the type, and Dim.TIME as a subtype"

    There are functional solutions, however I'm asking this to get a "best way" more than a "working way". Here's what I found:


    1. The simplest solution is to do use Literal: SomeGenericType[Literal[Dim.TIME]], but this is both annoying to write each time and counter-intuitive for people who expect Dim.TIME to behave as a type.


    2. Switching to classes, the most intuitive idea:

      class Dimension:
      pass

      class TIME(Dimension):
      pass


      doesn't work, because I want type(TIME) to be Dim, to reproduce Enum behavior


    3. That leads to using a metaclass:

      class Dimension(type):
      # ... complete __init__ and __new__ to get TIME.symbol = "t"

      class TIME(metaclass=Dimension, symbol="t"):
      pass


      This works, but I lose the ability to do Dim.TIME, to get Dim.TIME from Dim('t'), ...

    Continue reading...

Compartilhe esta Página