Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Wingardium Leviosa
Search
Serge Matveenko
April 25, 2014
Programming
0
150
Wingardium Leviosa
Python declarative magic basics
Serge Matveenko
April 25, 2014
Tweet
Share
More Decks by Serge Matveenko
See All by Serge Matveenko
Using NSQ in Python
lig
0
100
Build a container on Gitlab CI quest — Game Walkthrough
lig
0
180
Mnj — The MongoDB library which feels good
lig
0
140
Writing Dockerfile for a Python project the right way
lig
0
340
Pyventory for Ansible
lig
0
190
What time is it now?
lig
1
310
100% Test Covɘrage
lig
2
150
What in fact is this Python?
lig
2
180
Mnj — the MongoDB library which does it right
lig
1
260
Other Decks in Programming
See All in Programming
『自分のデータだけ見せたい!』を叶える──Laravel × Casbin で複雑権限をスッキリ解きほぐす 25 分
akitotsukahara
1
560
ruby.wasmで多人数リアルタイム通信ゲームを作ろう
lnit
2
280
5つのアンチパターンから学ぶLT設計
narihara
1
120
関数型まつり2025登壇資料「関数プログラミングと再帰」
taisontsukada
2
850
Elixir で IoT 開発、 Nerves なら簡単にできる!?
pojiro
1
150
AIエージェントはこう育てる - GitHub Copilot Agentとチームの共進化サイクル
koboriakira
0
440
Go1.25からのGOMAXPROCS
kuro_kurorrr
1
810
GraphRAGの仕組みまるわかり
tosuri13
8
490
AWS CDKの推しポイント 〜CloudFormationと比較してみた〜
akihisaikeda
3
310
ニーリーにおけるプロダクトエンジニア
nealle
0
550
CursorはMCPを使った方が良いぞ
taigakono
1
180
Gleamという選択肢
comamoca
6
760
Featured
See All Featured
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
15
1.5k
Side Projects
sachag
455
42k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
26
2.9k
Rebuilding a faster, lazier Slack
samanthasiow
82
9.1k
BBQ
matthewcrist
89
9.7k
Building Applications with DynamoDB
mza
95
6.5k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
16k
Docker and Python
trallard
44
3.4k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
34
5.9k
The Art of Programming - Codeland 2020
erikaheidi
54
13k
Bootstrapping a Software Product
garrettdimon
PRO
307
110k
The World Runs on Bad Software
bkeepers
PRO
69
11k
Transcript
«Вингардиум левиоса» Основы декларативной магии Сергей Матвеенко
«Harry Potter and the Philosopher's Stone»
http://xkcd.com/353/
➢ Описания: существительные и прилагательные, а не глаголы ➢ Независимость
от реализации ➢ Валидация без компиляции ➢ Не нужно уметь программировать ➢ GUI для редактирования ➢ Потому что это модно :) Декларативное программирование
➢ Декораторы ➢ Метаклассы ◦ Атрибуты классов ◦ Аргументы классов
◦ Аннотации аргументов методов ➢ Import hooks ◦ Модификация AST ◦ Генерация кода ➢ Внешние описания ◦ YAML Декларативность в Python
Декораторы @this_is_decorator(safe_mode=True) def method(arg1, arg2): # we will have just
a few lines here return arg1 + arg2 @abstractclass class ObjectBase: def foo(self): return NotImplemented
Метаклассы: атрибуты классов class MyClass(ObjectBase): sequence = True sorted =
False seq = MyClass() seq.extend([3, 2, 5]) print(seq) > [3, 2, 5]
Метаклассы: атрибуты классов class ObjectMeta(type): def __new__(cls, name, bases, attrs):
type_new = type.__new__(cls, name, bases, attrs) if attrs.get('sequence', False): # add sequence realization if attrs.get('sorted', False): # add sorted realization return type_new class ObjectBase(metaclass=ObjectMeta): pass class MyClass(ObjectBase): sequence = True sorted = False
Метаклассы: аргументы классов class SequenceMeta(type): def __new__(cls, name, bases, attrs,
sorted=False): type_new = type.__new__(cls, name, bases, attrs) if sorted: # add sorted realization return type_new class SortedSequence(metaclass=SequenceMeta, sorted=True): pass seq = SortedSequence()
Метаклассы: аннотации import inspect class StrictMeta(type): def __new__(cls, name, bases,
args): type_new = type.__new__(cls, name, bases, args) for attr_name in dir(type_new): method = getattr(type_new.attr_name) if callable(method): parameters = inspect.signature(method).parameters.values() # construct decorated method setattr(new_type, attr_name, method) return new_type class TextNumber(metaclass=StrictMeta): value = "0" def __add__(self, value: r'[\d\.]+'): # add implementation return self.value
Import hooks: модификация AST # smart_sql.py class MyImporter: def load_module(self,
name): # modify AST return module sys.path_hooks.insert(0, MyImporter) # prog.py import smart_sql query = ( id, Point(x, y) for id, x, y in "sql_table_name" if len([(x0, y0), (x, y)]) < 3)
Import hooks: генерация кода # smart_sql.py class MyImporter: def find_module(self,
fullname, path=None): # find path to DSL source file self.path = path return self def load_module(self, name): # generate and compile python module from DSL return module sys.meta_path.insert(0, MyImporter) # prog.py import smart_sql from dsl_queries import query result = query.find(radius)
YAML # pytest-yamlwsgi test_index: - path: / assert_status: 200 assert_contains:
Hello - path: / assert_contains: Hello - path: / assert_status: 200
Django ORM from django.db import models class Musician(models.Model): first_name =
models.CharField(max_length=50) last_name = models.CharField(max_length=50) instrument = models.CharField(max_length=100) class Album(models.Model): artist = models.ForeignKey(Musician) name = models.CharField(max_length=100) release_date = models.DateField() num_stars = models.IntegerField()
Django class-based generic views class PublisherDetail(DetailView): context_object_name = 'publisher' queryset
= Publisher.objects.all() class BookList(ListView): queryset = Book.objects.order_by('-publication_date') context_object_name = 'book_list' class AcmeBookList(ListView): context_object_name = 'book_list' queryset = Book.objects.filter(publisher__name='Acme') template_name = 'books/acme_list.html'
Function annotations # http://code.activestate.com/recipes/578528/ @typecheck def happy1(a:int, b:list, c:tuple=(1,2,3)) ->
float: return 3.14 @typecheck def happy_wo_annotation(a:int, b, c:tuple=(1,2,3)) -> float: return 3.14 @typecheck def unhappy1(a:int, b:str) -> float: return 314 # This can never succeed in return type
Вопросы? github.com/lig ptsecurity.com