27
МЕТАПРОГРАММИРОВАНИЕ КОД, УПРАВЛЯЮЩИЙ КОДОМ

ITCrowd - Метапрограммирование

Embed Size (px)

DESCRIPTION

Автор Данияр Супиев.

Citation preview

Page 1: ITCrowd - Метапрограммирование

МЕТАПРОГРАММИРОВАНИЕКОД, УПРАВЛЯЮЩИЙ КОДОМ

Page 2: ITCrowd - Метапрограммирование

ВИДЫ МЕТАПРОГРАММИРОВАНИЯ

Page 3: ITCrowd - Метапрограммирование

МАКРОСЫ/ШАБЛОНЫ

Page 4: ITCrowd - Метапрограммирование

ВНЕЯЗЫКОВЫЕ СРЕДСТВА

Page 5: ITCrowd - Метапрограммирование

DSLDOMAIN-SPECIFIC LANGUAGE

Page 6: ITCrowd - Метапрограммирование

ИНТЕРПРЕТАЦИЯ ПРОИЗВОЛЬНОГО КОДА

Page 7: ITCrowd - Метапрограммирование

ИНТРОСПЕКЦИЯ

Page 8: ITCrowd - Метапрограммирование

ИНТРОСПЕКЦИЯВозможность получить информацию о структуре базовых

элементов языка в ходе исполнения программы.

Возможность орудовать элементами программы с такой жестепенью свободы, как и с данными.

Page 9: ITCrowd - Метапрограммирование

ПОЛУЧАЕМ>>> def add(x, y): "adds y to x and returns result" return x + y

>>> print(add.__doc__)adds y to x and returns result>>> print(add.__name__)add

Page 10: ITCrowd - Метапрограммирование

ОРУДУЕМ>>> x = add>>> x(4, 5)9>>> print(x.__name__)add>>> x = {'add': add}>>> x['add'](2, 4)6

Page 11: ITCrowd - Метапрограммирование

И СНОВАdef make_adder(x): def adder(y): return x+y return adder

add_7 = make_adder(7)

>>> add_7(5)12

Page 12: ITCrowd - Метапрограммирование

БЛИЖЕ К ЖИЗНИdef less_than(x): def validator(y): if x >= y: raise ValueError("Value must be less than %s" % x) return validator

Page 13: ITCrowd - Метапрограммирование

ЕЩЁ БЛИЖЕ К ЖИЗНИ@Endpointdef max_int(x: Arg(int, required=True, validators=[val_gt(0), val_lt(200)]), y: Arg(int, validators=[val_in([1,10,105,124])])): return max(x,y)

Но об этом чуть позже :)

Page 14: ITCrowd - Метапрограммирование

МЕТАПРОГРАММИРОВАНИЕ ВPYTHON

Page 15: ITCrowd - Метапрограммирование

ДЕКОРАТОРЫ

Page 16: ITCrowd - Метапрограммирование

def cacher(func): cache = {} def wrapper(*args): if not args in cache: cache[args] = func(*args) return cache[args] return wrapper

def make_adder(x): def adder(y): return x+y return adder

make_adder = cacher(make_adder)

Page 17: ITCrowd - Метапрограммирование

@cacherdef make_adder(x): def adder(y): return x+y return adder

Page 18: ITCrowd - Метапрограммирование

ГЕНЕРАТОРЫ ДЕКОРАТОРОВdef cacher_gen(ttl) def cacher(func): cache = {} def wrapper(*args): if not args in cache or time() - ttl > cache[args][1]: cache[args] = (func(*args), time()) return cache[args] return wrapper return cacher

cacher_for_60_secs = cacher_gen(60)add = cacher_for_60_secs(add)# add = cacher_gen(60)(add)################# @cacher(60)# def add(x, y):# return x + y

Page 19: ITCrowd - Метапрограммирование

КАК ЭТИМ ПОЛЬЗУЮТСЯ@app.route("/")def hello(): return "Hello World!"

Page 20: ITCrowd - Метапрограммирование

ДЕСКРИПТОРЫ

Page 21: ITCrowd - Метапрограммирование

class A(object): a = "I am A"

x = A()

print(getattr(x, 'a'))# shows "I am A". Equivalent of print(x.a)

Page 22: ITCrowd - Метапрограммирование

class A(object): a = "I am A" def __getattribute__(self, name): return name

x = A()

print(getattr(x, 'a'))# shows "a". Equivalent of print(x.a)

Page 23: ITCrowd - Метапрограммирование

ТЕПЕРЬ К ВКУСНЕНЬКОМУ

Page 24: ITCrowd - Метапрограммирование

def val_lt(x):

@customize_error("Value of `{arg_name}` must be less than {min_val}", min_val=x) def validator(value): return value < x

return validator

Page 25: ITCrowd - Метапрограммирование

def customize_error(message=None, error_class=None, error_code=10000, **opt):

def wrapper(validator):

validator.message = message validator.error_class = error_class or ValidationError validator.error_code = error_code validator.opt = opt

return validator

return wrapper

Page 26: ITCrowd - Метапрограммирование

for validator_no, validator in enumerate(self.validators): if not validator(typed_value): template = getattr(validator, 'message', "Argument {arg_name} failed at validator #{validator_no}." "Given value: {value}")

error_class = getattr(validator, 'error_class', ValidationError)

error_code = getattr(validator, 'error_code', 10000)

opt = getattr(validator, 'opt', {})

raise error_class(message_template=template, error_code=error_code, arg_name=self.__name__, value=value, validator_no=validator_no, **opt)

Page 27: ITCrowd - Метапрограммирование

THE END