vitus_wagner: My photo 2005 (Default)
[personal profile] vitus_wagner
Выяснил что в стандартной библиотеке питона модуль collections, а в нем функция namedtuple. Позволяющая генерировать наборы данных с именованными полями и нулевым оверхедом. Более того named tuples - hashable, т.е. могут использоваться в качестве индекстов dict или элементов множества. И их очень удобно создавать из списков, dictionaries и тому подобных конструкций.

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

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

Down with static typing

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

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

Re: Down with static typing

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

Re: Down with static typing

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

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

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

Re: Down with static typing

Date: 2020-01-06 06:25 am (UTC)
yurikhan: (Default)
From: [personal profile] yurikhan

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

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 — примерно с той точки, когда проект естественным образом разделяется на несколько файлов.

Re: Down with static typing

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

Re: Down with static typing

Date: 2020-01-06 10:36 am (UTC)
avysk: (Default)
From: [personal profile] avysk
> Как написать 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.

Re: Down with static typing

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

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

Re: Down with static typing

Date: 2020-01-07 07:27 am (UTC)
yurikhan: (Default)
From: [personal profile] yurikhan

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

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

Date: 2020-01-05 08:03 pm (UTC)
livelight: (Default)
From: [personal profile] livelight
А почему именно set? Классическая реляционная алгебра не запрещает дубликаты tuples. Или в питоне "set" тоже их разрешает?

Date: 2020-01-05 09:10 pm (UTC)
phd_ru: (Default)
From: [personal profile] phd_ru
Нет, в set дублей нет.

Date: 2020-01-06 08:16 am (UTC)
yurikhan: (Default)
From: [personal profile] yurikhan

Дубликаты в данных легко и непринуждённо образуются в результате неаккуратной реализации проекции.

managers = [e.manager for e in employees]
assert (sorted(m.name for m in managers) ==
        sorted(set(m.name for m in managers)))  # fails

Допущение «set of named tuples», впрочем, эту проблему снимает. Если, конечно, нас устраивает иммутабельность объектов.

Date: 2020-01-06 09:08 am (UTC)
livelight: (Default)
From: [personal profile] livelight
Особенно это доставит радости, если надо делать агрегаты над проекцией. Например, count или sum.

Date: 2020-01-06 09:20 am (UTC)
yurikhan: (Default)
From: [personal profile] yurikhan
В моём случае результатом проекции был путь к файлу, над которым нужно было делать дорогостоящую (по процессору и I/O) обработку. И делать её один раз гораздо приятнее, чем 120 (хотя последнее и было безопасно).

Date: 2020-01-06 11:12 am (UTC)
livelight: (Default)
From: [personal profile] livelight
А вот для этого уже существуют взрослые СУБД: чтобы они сами думали, как выполнить 1 раз вычисления, которые, если в лоб выполнять написанное в запросе, придётся делать 120 раз. Но если автоматом схлопнуть все дубликаты, то проблемы будут уже с корректностью, а не производительностью.

Date: 2020-01-06 05:27 pm (UTC)
livelight: (Default)
From: [personal profile] livelight
Альтернатива - написать запрос на том же питоне, но включив мозг самостоятельно и явно указав, что в каком порядке вычислять, дабы оно вычислялось 1 раз, а не 120. Ну или вообще забить, в пределах мегабайта авось никто и не заметит на современном железе.

Date: 2020-01-06 12:29 pm (UTC)
livelight: (Default)
From: [personal profile] livelight
Дык, реляционная алгебра говорит, что результат должен быть одинаков. Потому что дубликаты она не удаляет.

Date: 2020-01-06 05:31 pm (UTC)
livelight: (Default)
From: [personal profile] livelight
Хм, и правда ж. Притом я ни минуты не сомневался, что "настоящая" алгебра отношений работает именно с такими множествами (где операция union all, например, смысла не имеет в принципе), но был уверен, что модель, с которой работает любая "реляционная" СУБД (с дубликатами, union all, select count group by и т.д.) как раз и называется "реляционной алгеброй"

Date: 2020-01-06 07:56 pm (UTC)
From: [personal profile] bowhill
Потому что на практике дубликаты в данных могут возникнуть только в результае ошибок ввода.

Это странное заблуждение, к тому же уникальность элементов набора -- это свойство области предметной области, а не области схемы БД.
Edited Date: 2020-01-06 07:58 pm (UTC)

Date: 2020-01-05 08:13 pm (UTC)
jno: (Default)
From: [personal profile] jno
А чего не сиквелобжектс имени бройтмана?
Или хочется свой бэкенд?

Date: 2020-01-05 09:11 pm (UTC)
phd_ru: (Default)
From: [personal profile] phd_ru
Насколько я понял, Витусу нужны операции над структурами данных, похожие на реляционные. А не SQL'чная БД.

Date: 2020-01-06 09:52 am (UTC)
beldmit: (Программизм)
From: [personal profile] beldmit
Какая разумная альтернатива ORM-ам на уровне CRUD? Собирать запрос руками? Спасибо, нафиг.

Date: 2020-01-06 12:31 pm (UTC)
beldmit: (Default)
From: [personal profile] beldmit
У меня типичный случай - view, где показывается несколько связанных объектов, соответствующих строкам из базы из разных таблиц. Если это редактура, то редактируются, как правило, поля одного объекта, и если нескольких, то контроллер разберёт, вытащит объекты и создаст запросы через объектный интерфейс. При этом ORM ещё и прикинет, надо ли ему обновлять единичный объект, если все старые значения совпадают с новыми, кажется.

Date: 2020-01-06 05:37 pm (UTC)
livelight: (Default)
From: [personal profile] livelight
Термином CRUD обычно называют (по крайней мере, в кровавом тырпрайзе) манипуляции объектами уровня предметной области. А как оно там должно в базу ложиться - никто обычно не хочет писать руками этот аццкий бойлерплейт, все хотят переложить эту работу на ORM.

Date: 2020-01-06 08:19 pm (UTC)
From: [personal profile] bowhill
Объекты — концепция иерархическая и инкапсуляционная, реляционная модель — очевидно, нет. Отобразить граф иерархией никак не получится и никакая «модность» объектов не поможет.

Date: 2020-01-07 01:25 pm (UTC)
From: [personal profile] kouzdra
Совершенно не обязательно. В OCaml (да и в Go) ничего такого особенно нет - соответствие объекта типу определяется исключительно фактической совместимостью по интерфейсу (кстати потому же в d Ocaml невозможен downcasting - для этого просто нет информации). Я кстати сильно подозреваю что упомянтое питоническое сперто как раз с Ocaml-евых объектов - там конечно оверхед не нулевой - там компилятор подбирает совершенный хеш, но подозреваю что по меркам питона - лишняя операция деления и лишняя косвенность - он нулевой

PS: Собственно в GCC 2.xx было подобное опытное расширение - сигнатуры, но не прижилось.

Date: 2020-01-07 03:25 pm (UTC)
From: [personal profile] bowhill
Можно, конечно, и структуру объектом назвать, это уже дело стиля. Ну а так есть и наследование, и инкапсуляция. То есть антагонисты реляционной модели.
Edited Date: 2020-01-07 03:29 pm (UTC)

Date: 2020-01-07 01:31 pm (UTC)
From: [personal profile] kouzdra
"нормальный" синтаксис для чего-то типа sql придуман четверть века как - у какого-то корейца - три типа коллекций - set (неупорядоченное без дублей), mutliset (с дублями) и bags - с дублями и упорядоченностью.

Элементы - ну обычные довольно по функциональщие записи с именованными полями и "алгебраические" типы (union-ы с именованными вариантами) ну и естественно любые элементы сами по себе могут быть коллекциями и проч.

Все хитрые "запросы" тривиально пишутся в хаскелльного стиля сверточном синтаксисе.

При этом у модели есть прямая проектция в sql, хотя автор развивал и свою: поскольку информации о том "что надо" тут гораздо больше можно этим попытаться воспользоваться для оптимизации.

На деле оказалось просто мало кому интересно - все рисуют на sql и довольны как питоны :)

Profile

vitus_wagner: My photo 2005 (Default)
vitus_wagner

May 2025

S M T W T F S
    1 2 3
4 56 7 8 9 10
11 12 131415 1617
18192021222324
25262728293031

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated May. 23rd, 2025 07:18 am
Powered by Dreamwidth Studios