ITCrowd - Метапрограммирование
-
Upload
itcrowd-almaty -
Category
Internet
-
view
510 -
download
0
description
Transcript of ITCrowd - Метапрограммирование
МЕТАПРОГРАММИРОВАНИЕКОД, УПРАВЛЯЮЩИЙ КОДОМ
ВИДЫ МЕТАПРОГРАММИРОВАНИЯ
МАКРОСЫ/ШАБЛОНЫ
ВНЕЯЗЫКОВЫЕ СРЕДСТВА
DSLDOMAIN-SPECIFIC LANGUAGE
ИНТЕРПРЕТАЦИЯ ПРОИЗВОЛЬНОГО КОДА
ИНТРОСПЕКЦИЯ
ИНТРОСПЕКЦИЯВозможность получить информацию о структуре базовых
элементов языка в ходе исполнения программы.
Возможность орудовать элементами программы с такой жестепенью свободы, как и с данными.
ПОЛУЧАЕМ>>> 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
ОРУДУЕМ>>> x = add>>> x(4, 5)9>>> print(x.__name__)add>>> x = {'add': add}>>> x['add'](2, 4)6
И СНОВАdef make_adder(x): def adder(y): return x+y return adder
add_7 = make_adder(7)
>>> add_7(5)12
БЛИЖЕ К ЖИЗНИdef less_than(x): def validator(y): if x >= y: raise ValueError("Value must be less than %s" % x) return validator
ЕЩЁ БЛИЖЕ К ЖИЗНИ@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)
Но об этом чуть позже :)
МЕТАПРОГРАММИРОВАНИЕ ВPYTHON
ДЕКОРАТОРЫ
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)
@cacherdef make_adder(x): def adder(y): return x+y return adder
ГЕНЕРАТОРЫ ДЕКОРАТОРОВ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
КАК ЭТИМ ПОЛЬЗУЮТСЯ@app.route("/")def hello(): return "Hello World!"
ДЕСКРИПТОРЫ
class A(object): a = "I am A"
x = A()
print(getattr(x, 'a'))# shows "I am A". Equivalent of print(x.a)
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)
ТЕПЕРЬ К ВКУСНЕНЬКОМУ
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
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
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)
THE END