Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Илья Беда (bro.engineering) - Data DSL на Python

Илья Беда (bro.engineering) - Data DSL на Python

Доклад с Moscow Python Conf 2016 (http://conf.python.ru)
Видео: https://conf.python.ru/data-dsl-na-python/

Все мы сталкиваемся с различными видами DSL. Это и общеизвестные внешние DSL - HTML CSS SQL, и более специализированные внутренние DSL - такие как модели и формы в веб-фреймворке Django.
- Чем же так хороши DSL?
- За счет узкой специализации языка вы можете выразить больше логики меньшим количеством конструкций.
- Почему бы не применять этот подход для решения повседневных задач.
- К сожалению, создание DSL сложная задача.
- Как можно упростить её?
- Нужно максимально использовать то, что уже готово. Зачем писать парсеры или разбирать AST python кода, когда можно использовать стандартные структуры данных, такие как списки и словари. Более того, в мире Clojure это является общепринятым стандартом.
В своем докладе я покажу примеры DSL, построенных на данных.
Вы узнаете, как реализовать DSL в python на основе списков и словарей. Я расскажу, в чем преимущество такого подхода, и на реальных примерах продемонстрирую для каких задач стоит применять данную технология, а для каких нет.

Moscow Python Meetup

October 12, 2016
Tweet

More Decks by Moscow Python Meetup

Other Decks in Programming

Transcript

  1. 2 КТО Я? Разрабатываю бэкэнды на python в течение 9

    лет Разрабатываю фронтенд на React в течение 2 лет Продвигаю функциональное программирование Провожу воркшопы и мастер-классы Люблю выступать на конференциях
  2. 5 WHAT WOULD YOU LIKE TO COMPLAIN ABOUT? [ ]

    Too much magic [ ] Too much boilerplate
  3. 6 WHAT WOULD ZEN OF PYTHON LIKE TO COMPLAIN ABOUT?

    [✅] Too much magic [ ] Too much boilerplate
  4. 7 WHAT WOULD ILYA BEDA LIKE TO COMPLAIN ABOUT? []

    Too much magic [✅] Too much boilerplate
  5. 9 КАК НАМ ПОЛЬЗОВАТЬСЯ ВСЕЙ МОЩНОСТЬЮ МЕТАПРОГРАММИРОВАНИЯ И БЛЮСТИ ZEN

    OF PYTHON в языке, совершенно не приспособленном к метапрограммированию?
  6. 13 МАКРОСЫ В CLOJURE ( d e f n i

    s ­ s m a l l ? [ n u m b e r ] ( i f ( < n u m b e r 1 0 0 ) " y e s " " n o " ) )
  7. 14 МАКРОСЫ В CLOJURE ( d e f n h

    e l l o ­ b i l l [ u s e r ­ n a m e ] ( w h e n ( = u s e r ­ n a m e " b i l l " ) ( p r i n t l n " h e l l o b i l l " ) ) )
  8. 15 МАКРОСЫ В CLOJURE ( m a c r o

    e x p a n d ' ( w h e n ( = u s e r ­ n a m e " b i l l " ) ( p r i n t l n " h e l l o b i l l " ) ) ) ( i f ( = u s e r ­ n a m e " b i l l " ) ( d o ( p r i n t l n " h e l l o b i l l " ) ) )
  9. 16 МАКРОСЫ В CLOJURE ( d e f n h

    e l l o ­ b i l l [ u s e r ­ n a m e ] ( w h e n ( = u s e r ­ n a m e " b i l l " ) ( p r i n t l n " h e l l o b i l l " ) ) ) ( d e f n h e l l o ­ b i l l [ u s e r ­ n a m e ] ( i f ( = u s e r ­ n a m e " b i l l " ) ( d o ( p r i n t l n " h e l l o b i l l " ) ) ) )
  10. 18 ВОЗМОЖНОСТЬ ТАКАЯ ЕСТЬ f r o m p a

    t t e r n s i m p o r t p a t t e r n s @ p a t t e r n s d e f f a c t o r i a l ( ) : i f 0 : 1 i f n i s i n t : n * f a c t o r i a l ( n ­ 1 ) i f [ ] : [ ] i f [ x ] + x s : [ f a c t o r i a l ( x ) ] + f a c t o r i a l ( x s ) i f { ' n ' : n , ' f ' : f } : f ( f a c t o r i a l ( n ) )
  11. 19 ВОЗМОЖНОСТЬ ТАКАЯ ЕСТЬ d e f f a c

    t o r i a l ( n ) : i f n = = 0 : r e t u r n 1 i f i s i n s t a n c e ( n , i n t ) : r e t u r n n * f a c t o r i a l ( n ­ 1 ) i f n = = [ ] : r e t u r n [ ] i f i s i n s t a n c e ( n , l i s t ) : r e t u r n [ f a c t o r i a l ( x [ 0 ] ) ] \ + f a c t o r i a l ( x [ 1 : ] ) i f i s i n s t a n c e ( n , d i c t ) : r e t u r n n [ ' f ' ] ( f a c t o r i a l ( n [ ' n ' ] ) )
  12. 21 PYTHON SOURCE CODE d e f i s _

    s m a l l ( n u m b e r ) : i f n u m b e r < 1 0 0 : r e t u r n " y e s " e l s e : r e t u r n " n o "
  13. 22 PYTHON AST F u n c t i o

    n ( N o n e , ' i s _ s m a l l ' , [ ' n u m b e r ' ] , 0 , N o n e , S t m t ( I f ( C o m p a r e ( N a m e ( ' n u m b e r ' ) , ' < ' , C o n s t ( 1 0 0 ) ) , S t m t ( R e t u r n ( C o n s t ( ' y e s ' ) ) ) , S t m t ( R e t u r n ( C o n s t ( ' n o ' ) ) ) ) ) )
  14. 25 CLOJURE SOURCE CODE ( d e f n i

    s ­ s m a l l ? [ n u m b e r ] ( i f ( < n u m b e r 1 0 0 ) " y e s " " n o " ) )
  15. 26 CLOJURE AST ' ( d e f n i

    s ­ s m a l l ? [ n u m b e r ] ( i f ( < n u m b e r 1 0 0 ) " y e s " " n o " ) )
  16. 32 HICCUP ( h t m l [ : s

    p a n { : c l a s s " f o o " } " b a r " ] )
  17. 33 HICCUP-PY h t m l ( [ " s

    p a n " , { " c l a s s " : " f o o " } " b a r " ] )
  18. 36 PYTHON-CERBERUS s c h e m a = {

    ' n a m e ' : { ' t y p e ' : ' s t r i n g ' , ' m a x l e n g t h ' : 1 0 } }
  19. 37 EVE D O M A I N = {

    ' w o r k s ' : { ' c a c h e _ c o n t r o l ' : ' m a x ­ a g e = 1 0 , m u s t ­ r e v a l i d a t e ' , ' c a c h e _ e x p i r e s ' : 1 0 , ' a d d i t i o n a l _ l o o k u p ' : { ' u r l ' : ' r e g e x ( " [ \ w ] + " ) ' , ' f i e l d ' : ' t i t l e ' } , ' s c h e m a ' : { ' t i t l e ' : { ' t y p e ' : ' s t r i n g ' , ' r e q u i r e d ' : T r u e , } } } }
  20. 43 ЗАДАЧА Новости (wysiwys, есть подблоки текста c wysiwys) Заметки

    (нет wysiwys, есть подблоки текста) Галерея (нет wysiwys, есть подблоки изображения) Документы (нет wysiwys, есть подблоки файлы)
  21. 53 НУЖНА КАСТОМИЗАЦИЯ Прокси модель на каждый случай Миксин на

    каждую опцию для админки Админка для каждой прокси модели со своим набором миксинов
  22. 55 У НАС УЖЕ ЕСТЬ ФОРМАЛИЗОВАННОЕ ЗНАНИЕ Новости (wysiwys, есть

    подблоки текста c wysiwys) Заметки (нет wysiwys, есть подблоки текста) Галерея (нет wysiwys, есть подблоки изображения) Документы (нет wysiwys, есть подблоки файлы)
  23. 56 ОПИШЕМ СТРУКТУРОЙ ДАННЫХ G R O U P _

    S C H E M A = { ' N e w s ' : { ' w y s i w y g ' : T r u e , ' h a s _ i m a g e s ' : F a l s e , ' h a s _ f i l e s ' : F a l s e , ' h a s _ s u b b l o c k ' : T r u e , } , ' N o t e ' : { ' w y s i w y g ' : F a l s e , ' h a s _ i m a g e s ' : F a l s e , ' h a s _ f i l e s ' : F a l s e , ' h a s _ s u b b l o c k ' : T r u e , } , ' G a l l e r y ' : { ' w y s i w y g ' : F a l s e , ' h a s _ i m a g e s ' : T r u e , ' h a s _ f i l e s ' : F a l s e , ' h a s _ s u b b l o c k ' : F a l s e , } , ' D o c u m e n t ' : { ' w y s i w y g ' : F a l s e , ' h a s _ i m a g e s ' : F a l s e , ' h a s _ f i l e s ' : T r u e , ' h a s _ s u b b l o c k ' : F a l s e , } }
  24. 57 ПИШЕМ ИНТЕРПРЕТАТОР 0 1 d e f c r

    e a t e _ f l a t b l o c k _ f o r _ g r o u p _ m o d e l ( n a m e , g r o u p _ i n f o ) : 0 2 c l a s s G r o u p B l o c k M a n a g e r ( m o d e l s . M a n a g e r ) : 0 3 d e f g e t _ q u e r y s e t ( s e l f ) : 0 4 r e t u r n s u p e r ( G r o u p B l o c k M a n a g e r , s e l f ) \ 0 5 . g e t _ q u e r y s e t ( ) \ 0 6 . f i l t e r ( g r o u p = n a m e . l o w e r ( ) ) 0 7 c l a s s G r o u p B l o c k M e t a : 0 8 p r o x y = T r u e 0 9 v e r b o s e _ n a m e = n a m e 1 0 v e r b o s e _ n a m e _ p l u r a l = g r o u p _ i n f o . g e t ( 1 1 ' v e r b o s e _ n a m e _ p l u r a l ' ) 1 2 1 3 c l a s s _ n a m e = ' { } B l o c k ' . f o r m a t ( n a m e ) 1 4 r e t u r n t y p e ( c l a s s _ n a m e , 1 5 ( B l o c k , ) , 1 6 { 1 7 ' o b j e c t s ' : G r o u p B l o c k M a n a g e r ( ) , 1 8 ' _ _ m o d u l e _ _ ' : _ _ n a m e _ _ , 1 9 ' M e t a ' : G r o u p B l o c k M e t a 2 0 } ) 2 1 2 2 g r o u p _ m o d e l s = { n a m e : c r e a t e _ f l a t b l o c k _ f o r _ g r o u p _ m o d e l ( 2 3 n a m e , g r o u p ) f o r n a m e , g r o u p i n g r o u p _ s c h e m a . i t e m s ( ) }
  25. 58 ПИШЕМ ИНТЕРПРЕТАТОР 0 1 b u i l d

    _ a d m i n _ c l a s s ( n a m e , g r o u p _ i n f o ) : 0 2 b a s e s = [ ] 0 3 i n l i n e s = [ ] 0 4 0 5 i f g r o u p _ i n f o [ ' w y s i w y g ' ] : 0 6 b a s e s . a p p e n d ( A d m i n W y s i w y g M i x i n ) 0 7 i f g r o u p _ i n f o [ ' h a s _ i m a g e s ' ] : 0 8 i n l i n e s . a p p e n d ( B l o c k I m a g e I n l i n e ) 0 9 i f g r o u p _ i n f o [ ' h a s _ f i l e s ' ] : 1 0 i n l i n e s . a p p e n d ( B l o c k F i l e I n l i n e ) 1 1 i f g r o u p _ i n f o [ ' h a s _ s u b b l o c k ' ] : 1 2 i n l i n e s . a p p e n d ( S u b B l o c k W y s i w y g A d m i n 1 3 i f g r o u p _ i n f o [ ' w y s i w y g ' ] e l s e S u b B l o c k A d m i n ) 1 4 1 5 b a s e s . a p p e n d ( M o d e l A d m i n ) 1 6 1 7 r e t u r n t y p e ( ' { } M o d e l A d m i n ' . f o r m a t ( n a m e ) , 1 8 t u p l e ( b a s e s ) , 1 9 { ' i n l i n e s ' : i n l i n e s } ) 2 0 2 1 2 2 f o r n a m e , g r o u p _ i n f o i n g r o u p _ s c h e m a . i t e m s ( ) : 2 3 a d m i n . s i t e . r e g i s t e r ( g r o u p _ m o d e l s [ n a m e ] , 2 4 b u i l d _ a d m i n _ c l a s s ( n a m e , g r o u p _ i n f o ) )
  26. 59 API G R O U P _ S C

    H E M A = { ' N e w s ' : { ' w y s i w y g ' : T r u e , ' h a s _ i m a g e s ' : F a l s e , ' h a s _ f i l e s ' : F a l s e , ' h a s _ s u b b l o c k ' : T r u e , } , ' N o t e ' : { ' w y s i w y g ' : F a l s e , ' h a s _ i m a g e s ' : F a l s e , ' h a s _ f i l e s ' : F a l s e , ' h a s _ s u b b l o c k ' : T r u e , } , ' G a l l e r y ' : { ' w y s i w y g ' : F a l s e , ' h a s _ i m a g e s ' : T r u e , ' h a s _ f i l e s ' : F a l s e , ' h a s _ s u b b l o c k ' : F a l s e , } , ' D o c u m e n t ' : { ' w y s i w y g ' : F a l s e , ' h a s _ i m a g e s ' : F a l s e , ' h a s _ f i l e s ' : T r u e , ' h a s _ s u b b l o c k ' : F a l s e , } }
  27. 60 АБСТРАКЦИЯ МОЖЕТ БЫТЬ ВЫШЕ N e w s :

    w y s i w y g : t r u e h a s _ i m a g e s : f a l s e h a s _ f i l e s : f a l s e h a s _ s u b b l o c k : t r u e N o t e : w y s i w y g : f a l s e h a s _ i m a g e s : f a l s e h a s _ f i l e s : f a l s e h a s _ s u b b l o c k : t r u e G a l l e r y : w y s i w y g : f a l s e h a s _ i m a g e s : t r u e h a s _ f i l e s : f a l s e h a s _ s u b b l o c k : f a l s e D o c u m e n t : w y s i w y g : f a l s e h a s _ i m a g e s : f a l s e h a s _ f i l e s : t r u e h a s _ s u b b l o c k : f a l s e
  28. 61 АБСТРАКЦИЯ МОЖЕТ БЫТЬ ЕЩЕ ВЫШЕ G R O U

    P _ S C H E M A = G r o u p S c h e m a . o b j e c t s . a s _ s c h e m a ( )