Могу ли я создать Python Enums для коэффициентов конверсии? - PullRequest
1 голос
/ 03 мая 2019

В настоящее время у меня есть две модели Django, определенные для DataUnit (например, кВт-ч, $, день, месяц и т. Д.) И RateUnit (например, $ / день, $ / кВт-ч и т. Д.).

Это оказывается полезным, так как я могу назначить единицы измерения различным значениям и гарантировать, что вычисления имеют смысл (например, X day * Y $ / day = $ Z), а также сделать недействительными вычисления, которые не следует делать (например,. DataUnit не равен знаменателю RateUnit).

Однако у меня есть кусок кода, который в настоящее время живет в Django и может быть полезен в общем контексте вне Django, ноопирается на RateUnit и DataUnit.

Могу ли я смоделировать что-то подобное в прямом Python?Я полагаю, что мог бы смоделировать DataUnit, используя перечисление, и все же сохранить это значение перечисления в Django EnumField.

Однако я не уверен, что делать с RateUnit.Я хотел бы иметь возможность составлять единицу измерения из двух единиц данных (один числитель и один знаменатель) таким образом, чтобы они могли жить как самостоятельно в модуле Python, так и сохраняться в модели Django в поле.

class DataUnit(ValidationModel):
    """
    Units of measure.

    Ex. kw, kwh, therms
    """

    name = models.CharField(max_length=8, unique=True)

    class Meta:
        ordering = ["id"]

    def __str__(self):
        return self.name


class RateUnit(ValidationModel):
    """
    Units of rate.

    Ex. $/kw, $/day, tCO2/kwh
    """

    numerator = models.ForeignKey(
        DataUnit, related_name="rate_unit_numerators", on_delete=models.PROTECT
    )
    denominator = models.ForeignKey(
        DataUnit,
        related_name="rate_unit_denominators",
        on_delete=models.PROTECT,
    )

    class Meta:
        ordering = ["id"]
        unique_together = ("numerator", "denominator")

    def __str__(self):
        return "{}/{}".format(self.numerator, self.denominator)

Это пример того, как я использовал бы его для целей проверки.

def validate_units(count_unit, rate_unit):
    """
    Validates that count_unit is a DataUnit and rate_unit is a RateUnit
    and that multiplying them yields a dollar amount.

    :param count_unit: DataUnit
    :param rate_unit: RateUnit
    """
    if not isinstance(count_unit, DataUnit) or not isinstance(
        rate_unit, RateUnit
    ):
        raise TypeError(
            "count_unit must be a DataUnit and rate_unit must be a "
            "RateUnit."
        )
    if (
        count_unit != rate_unit.denominator
        or rate_unit.numerator.name != "$"
    ):
        raise TypeError(
            "Multiplying count_unit by rate_unit must yield a dollar "
            "amount."
        )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...