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
110
Build a container on Gitlab CI quest — Game Walkthrough
lig
0
190
Mnj — The MongoDB library which feels good
lig
0
150
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
320
100% Test Covɘrage
lig
2
160
What in fact is this Python?
lig
2
190
Mnj — the MongoDB library which does it right
lig
1
270
Other Decks in Programming
See All in Programming
ライブ配信サービスの インフラのジレンマ -マルチクラウドに至ったワケ-
mirrativ
1
250
Portapad紹介プレゼンテーション
gotoumakakeru
1
130
サーバーサイドのビルド時間87倍高速化
plaidtech
PRO
0
170
Microsoft Orleans, Daprのアクターモデルを使い効率的に開発、デプロイを行うためのSekibanの試行錯誤 / Sekiban: Exploring Efficient Development and Deployment with Microsoft Orleans and Dapr Actor Models
tomohisa
0
160
コンテキストエンジニアリング Cursor編
kinopeee
1
640
あのころの iPod を どうにか再生させたい
orumin
2
2.5k
サイトを作ったらNFCタグキーホルダーを爆速で作れ!
yuukis
0
400
WebAssemblyインタプリタを書く ~Component Modelを添えて~
ruccho
1
870
オホーツクでコミュニティを立ち上げた理由―地方出身プログラマの挑戦 / TechRAMEN 2025 Conference
lemonade_37
2
480
DynamoDBは怖くない!〜テーブル設計の勘所とテスト戦略〜
hyamazaki
1
200
AI OCR API on Lambdaを Datadogで可視化してみた
nealle
0
140
The state patternの実践 個人開発で培ったpractice集
miyanokomiya
0
140
Featured
See All Featured
Automating Front-end Workflow
addyosmani
1370
200k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
29
2.8k
KATA
mclloyd
32
14k
Building Applications with DynamoDB
mza
96
6.6k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
53
2.9k
Intergalactic Javascript Robots from Outer Space
tanoku
272
27k
BBQ
matthewcrist
89
9.8k
Keith and Marios Guide to Fast Websites
keithpitt
411
22k
Reflections from 52 weeks, 52 projects
jeffersonlam
351
21k
Designing Experiences People Love
moore
142
24k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
126
53k
Making Projects Easy
brettharned
117
6.3k
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