Size: a a a

2019 July 05

SZ

Sergey Z in rannts
источник

AM

Artem Malyshev in rannts
Roman Bolkhovitin
это типа эквивалентно isinstance?
Нет, только по первому уровню.
источник

AM

Artem Malyshev in rannts
источник

RH

Roman Haritonov in rannts
Толи пример такой, толи я совсем не вижу преимуществ над разбитием на функции с параметрами или классы с методами.

Очень смущает, что дергается run в который передаются параметры, например
ProcessFile().run(
               image_path=image_path,
               save_path=ctx.save_path + image_path.split('/')[-1],
               initialized_model=ctx.initialized_model,
           )

Чем это отличается от обычных функций? И получается на этапе написания, у меня не будет автокомплита по параметрам?

Профит так и не понятен. Возможно в обработке ошибок? Но тут в примере тоже не вижу
источник

SA

Sergey Arkhipov in rannts
Я почему-то вспомнил фреймворки для тестирования Опенстека, где примерно то же делалось фикстурами пайтеста.

Вообще, если задуматься, то в этом коде истории собираются по принципу такой монадки в духе промисов. А были ли у тебя какие-то идеи по менее громоздкому синтаксису? Не могу сказать, что он сейчас шумный, но, скажем, даже в JS это можно было сделать немного элегантнее
источник

AM

Artem Malyshev in rannts
Roman Haritonov
Толи пример такой, толи я совсем не вижу преимуществ над разбитием на функции с параметрами или классы с методами.

Очень смущает, что дергается run в который передаются параметры, например
ProcessFile().run(
               image_path=image_path,
               save_path=ctx.save_path + image_path.split('/')[-1],
               initialized_model=ctx.initialized_model,
           )

Чем это отличается от обычных функций? И получается на этапе написания, у меня не будет автокомплита по параметрам?

Профит так и не понятен. Возможно в обработке ошибок? Но тут в примере тоже не вижу
https://dry-python.org/static/slides/ddd-toolkit-2.html#/23 перечислено тут, плюс скрины интеграций на следующих слайдах :)
источник

AM

Artem Malyshev in rannts
Sergey Arkhipov
Я почему-то вспомнил фреймворки для тестирования Опенстека, где примерно то же делалось фикстурами пайтеста.

Вообще, если задуматься, то в этом коде истории собираются по принципу такой монадки в духе промисов. А были ли у тебя какие-то идеи по менее громоздкому синтаксису? Не могу сказать, что он сейчас шумный, но, скажем, даже в JS это можно было сделать немного элегантнее
https://stories.readthedocs.io/en/latest/faq/#what-is-the-best-way-to-prototype-my-own-dsl-version
Мы открыты для предложений, сириусли :)
источник
2019 July 06

KK

Kirill (Cykooz) Kuzminykh in rannts
Сильно в dry не углублялся, но скажу про то что вижу в этой статье и предыдущих примерах.

Не понятно каким образом используется класс как основа стори. По факту он вообще не используется. Ни один метод в примерах не обращается к self.
А можно ли наследовать класс со story? Если да, то как добавить аргумент в дочернем классе? Полагаю, что использование декораторов не очень хорошо укладывается на наследование.
Если наследовать нельзя, то снова вопрос - зачем тут класс?
Можно ли сделать в одном классе две стори (run1 и run2)? В реальной практике такое у вас было? Или проще/правильнее сделать два класса? Если правильно иметь только один run, то почему бы не "захардкодить" во фреймворке его имя и тем самым отказаться от декораторов вокруг него, заменив их например на базовый класс (обычный или мета), который предполагает наличие в стори-классе "метода" run? У вас была необходимость назвать этот метод не run, а как-то по другому?
источник

AM

Artem Malyshev in rannts
Kirill (Cykooz) Kuzminykh
Сильно в dry не углублялся, но скажу про то что вижу в этой статье и предыдущих примерах.

Не понятно каким образом используется класс как основа стори. По факту он вообще не используется. Ни один метод в примерах не обращается к self.
А можно ли наследовать класс со story? Если да, то как добавить аргумент в дочернем классе? Полагаю, что использование декораторов не очень хорошо укладывается на наследование.
Если наследовать нельзя, то снова вопрос - зачем тут класс?
Можно ли сделать в одном классе две стори (run1 и run2)? В реальной практике такое у вас было? Или проще/правильнее сделать два класса? Если правильно иметь только один run, то почему бы не "захардкодить" во фреймворке его имя и тем самым отказаться от декораторов вокруг него, заменив их например на базовый класс (обычный или мета), который предполагает наличие в стори-классе "метода" run? У вас была необходимость назвать этот метод не run, а как-то по другому?
Класс используется для делегирования ответственности, как например показано тут: https://dry-python.org/static/slides/introducing-dry-python.html#/29

Класс со стори наследовать можно, это самый обычный класс. Добавить аргументы к сторе из родительского класса можно полностью переписав спеку и соответственно расширенным декоратором arguments. super в теле использовать не получится. story отрабатывает один раз во время определения класса.

В одном классе можно сделать две стори. Обычно мы так делаем когда run2 является вложенной сторёй в run1. Например, так удобно описывать правила валидации, чтобы не захламлять ими главную сторю, в которой будет один элегантный I.validate.

Если сторя run2 достаточно общая, мы выносим её в отдельный класс и прокидываем через аргументы __init__ как и обычные функции.

Сторю нужно называть по человечески.
class SubmitReport:
   @story
   def submit(I):
       ...
А запустить её можно двумя способами:
1. Вызвать как метод у класса SubmitReport().submit() - вернёт результат или кинет FailureException.
2. Вызвать через метод самой стори: SubmitReport().submit.run() - вернёт значение обёртку, с которым можно либо достать значение, либо достать причину ошибки предикатными методами или через библиотеку для pattern matching - pampy.
источник

KK

Kirill (Cykooz) Kuzminykh in rannts
Artem Malyshev
Класс используется для делегирования ответственности, как например показано тут: https://dry-python.org/static/slides/introducing-dry-python.html#/29

Класс со стори наследовать можно, это самый обычный класс. Добавить аргументы к сторе из родительского класса можно полностью переписав спеку и соответственно расширенным декоратором arguments. super в теле использовать не получится. story отрабатывает один раз во время определения класса.

В одном классе можно сделать две стори. Обычно мы так делаем когда run2 является вложенной сторёй в run1. Например, так удобно описывать правила валидации, чтобы не захламлять ими главную сторю, в которой будет один элегантный I.validate.

Если сторя run2 достаточно общая, мы выносим её в отдельный класс и прокидываем через аргументы __init__ как и обычные функции.

Сторю нужно называть по человечески.
class SubmitReport:
   @story
   def submit(I):
       ...
А запустить её можно двумя способами:
1. Вызвать как метод у класса SubmitReport().submit() - вернёт результат или кинет FailureException.
2. Вызвать через метод самой стори: SubmitReport().submit.run() - вернёт значение обёртку, с которым можно либо достать значение, либо достать причину ошибки предикатными методами или через библиотеку для pattern matching - pampy.
А не получится сделать как-то так, на обычных функциях:
@story
@arguments(...)
def worker_story(I):
 I(validate)
 I(do_work)

def validate(ctx): pass

def do_work(ctx): pass

И возможно получится даже к классам приделать это:
class Worker:
 @story
 @arguments(...)
 def run(self, I):
   I(self.validate)
   I(self.do_work)

 def validate(self, ctx): pass

 def do_work(self, ctx): pass

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

KK

Kirill (Cykooz) Kuzminykh in rannts
Заодно не придётся везде втыкать вот это
# noqa: Z444
Т.к. всё выглядит вполне классически для класса, по питонячи.
Разве что имя аргумента I выбивается из код-стайла.
источник

AM

Artem Malyshev in rannts
Только во время выполнения спеки нет ни self ни cls. То, что ты предлагаешь по сути уже есть в returns. Может тебе больше зайдут :)

Имя аргумента может быть любое, но я уже думаю над тем как отучить линтеры агриться на I.
источник

KK

Kirill (Cykooz) Kuzminykh in rannts
Т.е. у вас фактически метод run и не выполняется в тот момент, когда его вызывают в рантайме? Он у вас вызвается в процессе работы декоратора, и из него "достаётся" инфа о последовательности вызова "этапов"?
источник

KK

Kirill (Cykooz) Kuzminykh in rannts
Т.е. всяких циклов и if-чиков в этот run не получится напихать?
источник

AM

Artem Malyshev in rannts
Ага, всё именно так, как ты описал.
источник

AM

Artem Malyshev in rannts
А ещё мы напишем линтер, который будет за ifчики в бизнес логике с работы увольнять.
источник

KK

Kirill (Cykooz) Kuzminykh in rannts
Можно конечно self в моём варианте run попробовать заменить на cls, но что делать с остальными методами - не понятно. Вероятно можно как то cls.do_work превратить в self.do_work, когда стори будет выполняться в рантайме.
источник

KK

Kirill (Cykooz) Kuzminykh in rannts
Artem Malyshev
А ещё мы напишем линтер, который будет за ifчики в бизнес логике с работы увольнять.
Если циклы и if-чики не допустимы в стори, то почему было не сделать так, что бы run возвращала обычный список с "методами"? Или даже вместо run сделать просто "переменную в классе" со списком методов. Будет сразу понятно, что ни какой логики в pipeline вотнуть нелья.
источник

AM

Artem Malyshev in rannts
Kirill (Cykooz) Kuzminykh
Если циклы и if-чики не допустимы в стори, то почему было не сделать так, что бы run возвращала обычный список с "методами"? Или даже вместо run сделать просто "переменную в классе" со списком методов. Будет сразу понятно, что ни какой логики в pipeline вотнуть нелья.
Потому что мне кажется этот синтаксис шумным для глаз. А тут стройная спека, как на бумаге.

Ну и if так-то и в тело списка можно засунуть. И не будет соблазна сделать нечитаемый генератор в этом месте.
источник

💭П

💭 Руслан Прохоров in rannts
Artem Malyshev
Потому что мне кажется этот синтаксис шумным для глаз. А тут стройная спека, как на бумаге.

Ну и if так-то и в тело списка можно засунуть. И не будет соблазна сделать нечитаемый генератор в этом месте.
Я очень часто на бумаге пишу если тогда иначе
источник