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
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Serge Matveenko
April 25, 2014
Programming
170
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Wingardium Leviosa
Python declarative magic basics
Serge Matveenko
April 25, 2014
More Decks by Serge Matveenko
See All by Serge Matveenko
Using NSQ in Python
lig
0
160
Build a container on Gitlab CI quest — Game Walkthrough
lig
0
230
Mnj — The MongoDB library which feels good
lig
0
200
Writing Dockerfile for a Python project the right way
lig
0
400
Pyventory for Ansible
lig
0
220
What time is it now?
lig
1
380
100% Test Covɘrage
lig
2
210
What in fact is this Python?
lig
2
230
Mnj — the MongoDB library which does it right
lig
1
320
Other Decks in Programming
See All in Programming
XHTMLが残したもの
yosuke_furukawa
PRO
1
390
AI に Inclusive UI を書かせよう — Design Rules Skill で Compose UI を作り直す
theoriatec2024
1
440
MIZARU@SPAJAM2026 第二回予選
1901drama
0
100
Foundry Localでエージェント開発
seosoft
0
130
AWS Step Functions 大規模並列の壁を越える / jaws-sonic-2026-niigata-step-functions
kasacchiful
PRO
0
340
型解析で実現する Go の言語内 DSL / Conference に Go! タイムテーブルの歩き方 for Gophers
mazrean
0
120
이 함수, 실패하면 어떻게 되나요? null부터 Rich Errors까지, Kotlin 에러 처리 15년
haeti2
0
130
「AI時代、配布するPythonコードをどう守るか: 難読化の実験と判断軸」 #PyconJP2026
pkshadeck
PRO
2
160
信頼性の目標を誰も求めてない
shubox
0
490
AIは賢い。でも実行環境は? CLIおじさんがAI時代に伝えたいこと ~ CLIおじさんがAI時代に伝えたいこと ~
curekoshimizu
1
140
The Good Stuff, Not the Slop: Engineering High-Quality Android Apps with Modern AI Tooling
danybony
1
180
ソフトウェアラスタライザ
fadis
1
780
Featured
See All Featured
The SEO identity crisis: Don't let AI make you average
varn
0
550
Facilitating Awesome Meetings
lara
57
7.1k
Darren the Foodie - Storyboard
khoart
PRO
3
3.9k
Bioeconomy Workshop: Dr. Julius Ecuru, Opportunities for a Bioeconomy in West Africa
akademiya2063
PRO
1
340
How Software Deployment tools have changed in the past 20 years
geshan
1
34k
SEO for Brand Visibility & Recognition
aleyda
0
4.7k
Tell your own story through comics
letsgokoyo
1
1.1k
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
49
10k
Discover your Explorer Soul
emna__ayadi
2
1.3k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
360
30k
技術選定の審美眼(2025年版) / Understanding the Spiral of Technologies 2025 edition
twada
PRO
120
120k
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