vitus_wagner: My photo 2005 (Default)
vitus_wagner ([personal profile] vitus_wagner) wrote2020-01-05 09:37 pm

Питонистическое.

Выяснил что в стандартной библиотеке питона модуль collections, а в нем функция namedtuple. Позволяющая генерировать наборы данных с именованными полями и нулевым оверхедом. Более того named tuples - hashable, т.е. могут использоваться в качестве индекстов dict или элементов множества. И их очень удобно создавать из списков, dictionaries и тому подобных конструкций.

Теперь хочу реализацию операций реляционной алгебры над set of named tuples.
avysk: (Default)

[personal profile] avysk 2020-01-05 07:09 pm (UTC)(link)
А модуле typing стандартной библиотеки есть NamedTuple, который делает то же самое, но помогает программе развалиться не в рантайме, а при статической проверке типов чем-нибудь типа mypy.
phd_ru: (Default)

Down with static typing

[personal profile] phd_ru 2020-01-05 09:09 pm (UTC)(link)
Никак не могу понять — зачем в языке, ориентированном на duck typing, статическая типизация? И надо же, duck typing — единственное, чего mypy не умеет.

А кому нужны Жаба и ЦиПлюкПлюк — пусть идут в Жабу и т.д.
avysk: (Default)

Re: Down with static typing

[personal profile] avysk 2020-01-05 10:54 pm (UTC)(link)
mypy -- это вовсе не статическая типизация. Это проверка type hints (описанных в PEP 483 и 484) там, где они явно написаны, а где не написаны -- то и ладно. Duck typing это никаким образом не отменяет. Но оно иногда сильно помогает от идиотских опечаток, когда никакого duck typing не нужно, функция возвращает тапл из числа и строки -- а код, вызывающий эту функцию, перепутал строку и число местами.
Edited 2020-01-05 22:55 (UTC)
phd_ru: (Default)

Re: Down with static typing

[personal profile] phd_ru 2020-01-06 12:08 am (UTC)(link)
Я считаю, что от mypy больше вреда, чем пользы.

В тех проектах, где я видел использование mypy — отсутствие type hints выдавало ошибку. Не знаю, можно ли это отключить. Я вместо этого предпочитаю просто не иметь дела с mypy.

Как написать type hint "в этом месте мне нужен экземпляр класса, имеющий метод .read() без параметров, возвращающий строку"?
yurikhan: (Default)

Re: Down with static typing

[personal profile] yurikhan 2020-01-06 06:25 am (UTC)(link)

В общем виде это называется «протокол»:

from typing_extensions import Protocol

class SupportsRead(Protocol):
    def read(self) -> str:
        ...


class MyReader:  # look ma, no inheritance
    def read(self) -> str:
        return 'hello world'


def test(reader: SupportsRead) -> None:
    pass

test(open('/dev/null'))
test(MyReader())
test(test)  # fails

В частном случае вообще может подойти typing.TextIO.

И да, я применяю mypy в боевом проекте. Польза от наличия аннотаций типов как документации для читателя/мейнтейнера кода настаёт при размере проекта больше 150 SLOC. А польза от mypy — примерно с той точки, когда проект естественным образом разделяется на несколько файлов.

phd_ru: (Default)

Re: Down with static typing

[personal profile] phd_ru 2020-01-06 01:56 pm (UTC)(link)
Спасибо! mypy таки дозрел до интерфейсов, замаскированных под именем протоколов. :-)
avysk: (Default)

Re: Down with static typing

[personal profile] avysk 2020-01-06 10:36 am (UTC)(link)
> Как написать type hint "в этом месте мне нужен экземпляр класса, имеющий метод .read() без параметров, возвращающий строку"?

https://mypy.readthedocs.io/en/latest/protocols.html#protocol-types



from abc import abstractmethod
from typing import Protocol

class SupportsRead(Protocol):
    @abstractmethod
    def read(self) -> str:
        pass


def fun(something: SupportsRead):
    print(something.read())


class Good:
    def read(self) -> str:
        return "foobar"


class Bad:
    def read(self) -> int:
        return 42


fun(Good())
fun(Bad())


foobar.py:25: error: Argument 1 to "fun" has incompatible type "Bad"; expected "SupportsRead"
foobar.py:25: note: Following member(s) of "Bad" have conflicts:
foobar.py:25: note:     Expected:
foobar.py:25: note:         def read(self) -> str
foobar.py:25: note:     Got:
foobar.py:25: note:         def read(self) -> int
Found 1 error in 1 file (checked 1 source file)


Только не забывайте, что mypy -- это не статическая типизация, а проверка type hints там, где программист счёл их нужными. Если не написать type hints, ничего не будет -- например, если убрать "-> int" в описании класса Bad, ошибка исчезнет.

> В тех проектах, где я видел использование mypy — отсутствие type hints выдавало ошибку.

Я так понимаю, что Вы не видели использование mypy.
phd_ru: (Default)

Re: Down with static typing

[personal profile] phd_ru 2020-01-06 01:58 pm (UTC)(link)
Спасибо! mypy таки дозрел до интерфейсов, замаскированных под именем протоколов. :-)

Я видел использование mypy в нескольких крупных проектах и сильно его там невзлюбил. :-( Отсутствие type hints там везеде приводило к ошибкам.
yurikhan: (Default)

Re: Down with static typing

[personal profile] yurikhan 2020-01-07 07:27 am (UTC)(link)

Выдавать ошибки на отсутствие аннотаций — это опция. И даже выключенная по умолчанию. Включить её принимает решение мейнтейнер проекта, в тот момент, когда проект уже достаточно аннотирован, или одновременно с решением аннотировать его весь.

В отдельных редких местах, где действительно применяется duck typing и кажется нецелесообразным прямо сейчас прописывать весь протокол, — ошибку можно заткнуть указанием аннотации Any (а лучше — отдельным типом, определённым как синоним Any, с TODO’шкой когда-нибудь это расписать).