Python3: единичные меры, связанные с переменными - PullRequest
0 голосов
/ 08 июня 2018

Как десятилетний программист, я усвоил трудный путь, что физическим значениям имеет смысл помещать тег в переменную.В C или C ++ я делаю это с помощью встроенных замечаний:

Код в C

double /*MOhm*/ resistance(double R1 /*MOhm*/, double R2 /*MOhm*/){
    return R1+R2;
}

цель комментария: входные значения - МОм, а выходные -Мом тоже.

Есть ли элегантный Pythonian способ сделать то же самое?Как нет встроенных замечаний, как это можно сделать?Для меня очень важно иметь читаемый код, который легко может понять другой человек.

Ответы [ 2 ]

0 голосов
/ 08 июня 2018

Будьте конкретны: определите тип (на самом деле псевдоним типа), который точно описывает то, что вы ожидаете.

MOhm = float

def resistance(r1: MOhm, r2: MOhm) -> MOhm:
    return r1 + r2

(Python 3 действительно допускает идентификаторы Unicode, так что вы можете получить фантазию и написать

# That's M\u2126, M + OHM SIGN
MΩ = float

def resistance(r1: MΩ, r2: MΩ) -> MΩ:
    return r1 + r2

Однако, U+03a9 (Ω, ГРЕЧЕСКИЙ КАПИТАЛ ПИСЬМО ОМЕГА) и U+2126 (Ω, ОМ-ЗНАК) в лучшем случае трудно отличить друг от друга, поэтому я бы избегал такого рода идентификатора в реальном коде.)


Вы можете пойти еще дальше и определить real новый тип, который будут применяться такими инструментами, как mypy.Однако это требует небольших затрат времени выполнения.

from typing import NewType

Ohm = NewType("Ohm", float)
MOhm = NewType("MOhm", float)

def resistance(r1: MOhm, r2: MOhm) -> MOhm:
    return MOhm(r1 + r2)

x: Ohm = Ohm(3.0)
y: MOhm = MOhm(4.0)

# mypy error, resistance expects its first argument to have type MOHm, not OHm
print(resistance(x, y))

NewType - вспомогательная функция для определения таких классов, как

class Ohm(float):
    pass

class MOhm(float):
    pass

Во время выполнения все три класса ведут себятот же самый.Такие инструменты, как mypy, однако, будут обрабатывать их как отдельные классы, заставляя вас усерднее работать, чтобы обеспечить проверку типов кода.Труднее случайно ошибиться в единицах измерения, когда вам нужно быть конкретным в отношении значений, которые вы передаете.

0 голосов
/ 08 июня 2018

В Python вы должны использовать функцию docstring , описывающую параметры и возвращаемые значения.Например, используя синтаксис sphinx :

def resistance(r1: float, r2: float) -> float:
    """
    Calculate resistance.

    :param r1: resistance in MOhm
    :param r2: resistance in MOhm
    :returns: total resistance in MOhm
    """
    return r1 + r2

Строки документов в стандартных форматах могут быть проанализированы средами IDE, чтобы предоставить вам полезное автозаполнение и т. Д.

...