"Вингардиум Левиоса”. Или основы декларативной магии...
description
Transcript of "Вингардиум Левиоса”. Или основы декларативной магии...
«Вингардиум левиоса»Основы декларативной магии
Сергей Матвеенко
«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
@abstractclassclass 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.pyclass MyImporter: def load_module(self, name): # modify AST return modulesys.path_hooks.insert(0, MyImporter)
# prog.pyimport smart_sqlquery = (
id, Point(x, y)for id, x, yin "sql_table_name"if len([(x0, y0), (x, y)]) < 3)
Import hooks: генерация кода# smart_sql.pyclass 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 modulesys.meta_path.insert(0, MyImporter)
# prog.pyimport smart_sqlfrom dsl_queries import queryresult = query.find(radius)
YAML# pytest-yamlwsgitest_index:
- path: / assert_status: 200 assert_contains: Hello
- path: / assert_contains: Hello
- path: / assert_status: 200
Django ORMfrom 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 viewsclass 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/
@typecheckdef happy1(a:int, b:list, c:tuple=(1,2,3)) -> float: return 3.14
@typecheckdef happy_wo_annotation(a:int, b, c:tuple=(1,2,3)) -> float: return 3.14
@typecheckdef unhappy1(a:int, b:str) -> float: return 314 # This can never succeed in return type
Вопросы?
github.com/lig
ptsecurity.com