Соглашение, чтобы отличить псевдонимы типа от реальных классов? - PullRequest
0 голосов
/ 06 мая 2018

Модуль ввода позволяет назначать сигнатуры сложных типов псевдонимам , которые затем могут использоваться взаимозаменяемо с фактическим типом. Похоже, в этом проблема того, что он путает псевдонимы типов с реальными классами, т. Е. В определении, подобном этому

def foo(obj: MyComplexObject):
    ...

невозможно определить, реализован ли где-нибудь MyComplexObject как класс или это просто псевдоним типа. Мне кажется, это неудачный источник путаницы, особенно когда псевдоним (ре) используется далеко от его первоначального определения. Это общепризнанно или существует соглашение, позволяющее как-то отличать псевдонимы типов от реальных классов?

Ответы [ 2 ]

0 голосов
/ 07 мая 2018

Я считаю, что псевдонимы типов и обычные типы неразличимы по дизайну: псевдонимы типов предназначены для точного замещения любого типа, к которому они относятся.

Таким образом, для использования вашего примера не обязательно имеет значение, является ли MyComplexObject фактическим классом или псевдонимом типа: они оба ведут себя одинаково во время выполнения и статической проверки типов.

И поскольку средство проверки типов может дать вам немедленную обратную связь о том, используете ли вы obj безопасным для типов способом, у вас есть минимальные возможности запутаться: либо вы будете использовать параметр obj правильно иначе вы получите немедленный отзыв. (И аналогично, такие IDE, как Pycharm, которые понимают семантику PEP 484, также будут понимать псевдонимы типов и будут корректно автоматически заполнять / отмечать ошибки.)

Стоит также отметить, что в случае, когда вы специально присваиваете псевдоним другим классам, псевдоним и исходный класс буквально неразличимы во время выполнения: они обе переменные, которые ссылаются на один и тот же объект базового типа. (Так что, возможно, в этом нет ничего сложного: и псевдоним, и исходный тип - это «одно и то же».)

Следовательно, было очень мало стимулов найти соглашение об именах для различения типов и псевдонимов типов - на самом деле это не является проблемой на практике.


Тем не менее, - это некоторые неявные соглашения о том, когда использовать псевдонимы типа. Например, люди обычно не используют псевдонимы классов напрямую: псевдонимы типов, как сказал Итан, в основном предназначены для упрощения составных типов больших размеров, которые повторяются в нескольких местах.

Это означает, что псевдонимы типов в основном используются, когда в противном случае у вас была бы куча действительно уродливых сигнатур типов. Затем это становится «компромиссным» видом: читателю действительно нужно тратить время на поиск определения псевдонима и кэшировать его в своей голове, но как только они это сделают, чтение остальной части кода должно быть намного приятнее.

Так что, если вы все еще находите псевдонимы типов потенциально запутанными и предпочитаете избегать их использования без необходимости, это прекрасно: это то, что в большинстве случаев делают все остальные. Единственная разница сводится к тому, когда вы пересекаете этот переломный момент от «ненужного» к «необходимому».

0 голосов
/ 06 мая 2018

Не существует официального соглашения о различении двух.

Псевдонимы типов очень похожи на typedefs в других языках. Однако, по соглашению, псевдонимы типов используются для сложных комбинаций типов, таких как Message = Union[str, MyClass1, MyClass2, OtherClass], где многократное выписывание полного объединения было бы громоздким. Таким образом, аннотация одного имени должна быть либо: тип, либо некоторая комбинация типов, которые являются псевдонимами. Вы должны перейти к определению этого имени, чтобы отличить их.

...