рдПрдиреЛрдЯреЗрд╢рди рдХреЗ рд▓рд┐рдП рдПрдХ рдЙрдкрдпреЛрдЧ рдорд╛рдорд▓рд╛

рдореИрдВ рдЕрднреА рдШреЛрд╖рдгрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдХрд┐ рдпрд╣рд╛рдВ, рдПрдиреЛрдЯреЗрд╢рди рдХреЗ рддрд╣рдд, рд╣рдорд╛рд░рд╛ рдорддрд▓рдм рдбреЗрдХреЛрд░реЗрдЯрд░ рдирд╣реАрдВ рд╣реИ ред рдФрд░ рдореБрдЭреЗ рдЗрд╕ рдмрд╛рдд рдХреА рдЬрд╛рдирдХрд╛рд░реА рдирд╣реАрдВ рд╣реИ рдХрд┐ рд╕рдЬрд╛рд╡рдЯ рдХрд░рдиреЗ рд╡рд╛рд▓реЛрдВ рдХреЛ рдХрднреА-рдХрднреА рдПрдиреЛрдЯреЗрд╢рди рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред



рдореБрдЭреЗ рд╣рд╛рд▓ рд╣реА рдореЗрдВ рдкрддрд╛ рдЪрд▓рд╛ рдХрд┐ рдЕрдЬрдЧрд░ рдореЗрдВ рдПрдХ рд╡рд┐рд╢реЗрд╖рддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рдореИрдВ рд▓рдВрдмреЗ рд╕рдордп рд╕реЗ рджреЗрдЦ рд░рд╣рд╛ рд╣реВрдВ - рдлреАрдЪрд░ рдПрдиреЛрдЯреЗрд╢рди ред рдпрд╣ рдлрд╝рдВрдХреНрд╢рди рдШреЛрд╖рдгрд╛ рдореЗрдВ рдЗрд╕рдХреЗ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдорд╛рдкрджрдВрдбреЛрдВ рдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдкрд░ рдХрд┐рд╕реА рднреА рдЬрд╛рдирдХрд╛рд░реА рдХреЛ рджреВрд░ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдЕрд╡рд╕рд░ рд╣реИред



рдпрд╣рд╛рдБ PEP рд╕реЗ рдПрдХ рд╡рд┐рд╣рд┐рдд рдЙрджрд╛рд╣рд░рдг рд╣реИ:



def compile(source: "something compilable", filename: "where the compilable thing comes from", mode: "is this a single statement or a suite?"): ...
      
      







рдиреАрдЪреЗ рдЙрд╕реА рд╕реНрдерд╛рди рдкрд░, рдЙрджрд╛рд╣рд░рдг рджрд┐рдП рдЧрдП рд╣реИрдВ рдЬреЛ рдпрд╣ рд╕реНрдкрд╖реНрдЯ рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рдорд╛рдкрджрдВрдбреЛрдВ рдкрд░ рдЯрд┐рдкреНрдкрдгреА рдХрд░рдирд╛ рдЗрд╕ рд╕реБрд╡рд┐рдзрд╛ рдХрд╛ рдПрдХрдорд╛рддреНрд░ рд╕рдВрднрд╡ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рд╣реИред рдЗрд╕рдиреЗ рдореБрдЭреЗ рдПрдХ рдкреБрд░рд╛рдиреА рдкрд░реЗрд╢рд╛рдиреА рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░реЗрд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд┐рд╕рдиреЗ рдореЗрд░реЗ рддрдВрддреНрд░рд┐рдХрд╛ рддрдВрддреНрд░ рдХреЛ рдПрдХ рд╕рднреНрдп рд╕рдордп рдХреЗ рд▓рд┐рдП рдЧреНрд░рд╕реНрдд рдХрд░ рджрд┐рдпрд╛ рд╣реИред рдЕрд░реНрдерд╛рддреН, рдлреНрд▓рд╛рд╕реНрдХ рдореЗрдВ рд░реВрдкреЛрдВ рд╕реЗ рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ ред







рд╕рдорд╕реНрдпрд╛





рдЬрдм рдЖрдк рдХрд┐рд╕реА рдХреНрд╡реЗрд░реА рд╕реЗ рддрд░реНрдХ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдЙрдиреНрд╣реЗрдВ рд╕реНрд╡рдпрдВ рд▓реЗрдиреЗ рдХреЗ рд▓рд┐рдП рдордЬрдмреВрд░ рд╣реЛрддреЗ рд╣реИрдВред рд╣рд░ рдмрд╛рд░ред рд╣рд░ рддрд░реНрдХред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЖрдк рд╕реАрдзреЗ рдЕрдкрдиреЗ рд╕рдорд╛рдкрди рдмрд┐рдВрджреБ рдХреЗ рд╢рд░реАрд░ рдореЗрдВ рдЗрди рддрд░реНрдХреЛрдВ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдордЬрдмреВрд░ рд╣реИрдВред рдпрд╣ рдПрдХ рдирд┐рдпрдо рдХреЗ рд░реВрдк рдореЗрдВ рджрд┐рдЦрддрд╛ рд╣реИ, рдмрд╣реБрдд рдЕрдиреБрдХреВрд▓ рдирд╣реАрдВ рд╣реИред



рдпрд╣рд╛рдБ рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╣реИ:



 @app.route('/ugly_calc') def ugly_calc(): x, y = int(request.args['x']), int(request.args['y']) op = OPERATION[request.args['op']] #      . ,   тАФ      (,   ) return str(op(x, y))
      
      







рдирд┐рдпрдВрддреНрд░рдХ рдореЗрдВ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╕рд╛рдл, рдорд╛рдиреНрдп рдФрд░ рд╕рддреНрдпрд╛рдкрд┐рдд рддрд░реНрдХ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдЕрдзрд┐рдХ рддрд░реНрдХрд╕рдВрдЧрдд рд╣реЛрдЧрд╛:



 @app.route('/calc') def calc(x:Arg(int), y:Arg(int), op:Arg(_from=OPERATION)): return str(op(x, y))
      
      







рдХреЛрдб рдкрдардиреАрдпрддрд╛ рдФрд░ рддрд░реНрдХ рдореЗрдВ рд╣рд╛рд╕рд┐рд▓ рдХрд░ рд▓рд┐рдпрд╛, рдФрд░ рдирд┐рдпрдВрддреНрд░рдХ рдХрд╛ рдЖрдХрд╛рд░ рдкрд░рд┐рдЪрд╛рд▓рди рдХреА рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╕рдВрдЦреНрдпрд╛ рддрдХ рдХрдо рд╣реЛ рдЧрдпрд╛ред



рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдЪрд▓рд╛рдИ





рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдореЗрдВ рдПрдХ рддрд░реНрдХ рд╡рд░реНрдЧ рдХреЛ рдлреЗрдВрдХрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред



рд╣рдо рдпрд╣рд╛рдВ рд╕реЗ рдЗрд╕рдХреЗ рд▓рд┐рдП рдЖрдзрд╛рд░ рд▓реЗрдВрдЧреЗред рдмрд╛рд╣рд░ рдлреЗрдВрдХ рджреЛ рдЬреЛ рд╣рдореЗрдВ рдЕрдм рдЬрд╝рд░реВрд░рдд рдирд╣реАрдВ рд╣реИ, рдФрд░ рд╡реЛрдЗрд▓рд╛!



 class Arg(object): """ A request argument. """ def __init__(self, p_type=str, default=None): self.type = p_type self.default = default def _validate(self, value): """Perform conversion and validation on ``value``.""" return self.type(value) def validated(self, value): """ Convert and validate the given value according to the ``p_type`` Sets default if value is None """ if value is None: return self.default or self.type() return self._validate(value)
      
      







рд╣рд╛рдВ, рддрд░реНрдХ рдХрд╛ рд╡рд░реНрдЧ рдЕрднреА рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдиреНрдпреВрдирддрд░ рд╣реЛрдЧрд╛ред рдЕрдВрдд рдореЗрдВ, рд╣рдо рдХрд┐рд╕реА рднреА рд╕рдордп рд╕рднреА рдкреНрд░рдХрд╛рд░ рдХреЗ рдЖрд╡рд╢реНрдпрдХ рдФрд░ рдкреНрд░реЗрд╖рд┐рдд рд╕рддреНрдпрд╛рдкрдирдХрд░реНрддрд╛рдУрдВ рдХреЗ рд╕рд╛рде рдЗрд╕рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдВрдЧреЗред



рдЕрдм рд╣рдореЗрдВ рдПрдХ рдРрд╕реА рдЪреАрдЬрд╝ рдХрд░рдиреЗ рдХреА рдЬрд╝рд░реВрд░рдд рд╣реИ рдЬреЛ "рдЧрдВрджреЗ" рддрд░реНрдХреЛрдВ рд╕реЗ рд╢рдмреНрджрдХреЛрд╢ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдЧреА, рдФрд░ "рд╕реНрд╡рдЪреНрдЫ" рд▓реЛрдЧреЛрдВ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░ рджреЗрдЧреАред



рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдпрд╣рд╛рдВ рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧрд╛ рдХрд┐ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдЕрд╕рд╛рдЗрди рдХрд┐рдП рдЧрдП рдПрдиреЛрдЯреЗрд╢рди рдПрдХ рдРрд╕рд╛ рд╢рдмреНрджрдХреЛрд╢ __annotations__



рдЬреЛ __annotations__



рд╡рд┐рд╢реЗрд╖рддрд╛ рдореЗрдВ __annotations__



ред



 >>> def lol(yep, foo: "woof", bar: 32*2): pass >>> lol.__annotations__ {'foo': 'woof', 'bar': 64}
      
      







рдЗрд╕рд▓рд┐рдП, рдЬреИрд╕рд╛ рдХрд┐ рд╣рдо рджреЗрдЦрддреЗ рд╣реИрдВ, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╕рднреА рддрддреНрд╡реЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рд╢рдмреНрджрдХреЛрд╢ рд╣реИ рдЬрд┐рд╕реЗ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдЕрдиреНрдп рддрд░реНрдХреЛрдВ рдХреЗ рдЕрд╕реНрддрд┐рддреНрд╡ рдХреЛ рднреА рдирд╣реАрдВ рднреВрд▓рдирд╛ рдЪрд╛рд╣рд┐рдПред рдпрд╣ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рдирд╣реАрдВ рд╣реЛрдЧрд╛ рдЕрдЧрд░ lol



рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдЗрд╕рдХрд╛ yep



рдирд╣реАрдВ рдорд┐рд▓рддрд╛ рд╣реИред



рдХреБрдЫ рдореИрдВрдиреЗ рдХрдерд╛ рд╕реЗ рд╡рд╛рдкрд╕ рдХрджрдо рд░рдЦрд╛ред рд╣рдо рдЬрд╛рд░реА рд░рдЦрддреЗ рд╣реИрдВ:



 class Parser(object): def __call__(self, dct): """ Just for simplify """ return self.validated(dct) def __init__(self, structure): self.structure = structure def validated(self, dct): for key, arg_instatce in self.structure.items(): dct[key] = arg_instatce(dct.get(key, None)) return dct
      
      







рдпрд╣ рд╡рд░реНрдЧ рддреАрди рд░реВрдмрд▓ рдХреА рддрд░рд╣ рд╕рд░рд▓ рд╣реИред рдЗрд╕рдХреЗ рдЙрджрд╛рд╣рд░рдг рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рд╛рдкреНрдд рдкреИрд░рд╛рдореАрдЯрд░ рдХреЛ рдорд╛рдиреНрдп рдХрд░рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдХрд╛ рдирд╛рдо рдкреНрд░рд╛рдкреНрдд рд╢рдмреНрджрдХреЛрд╢ рдореЗрдВ рдФрд░ рдкреИрд░рд╛рдореАрдЯрд░ рд╕рдВрд░рдЪрдирд╛ рдореЗрдВ рд╣реИ, рдФрд░ рдлрд┐рд░ рдмрджрд▓реЗ рд╣реБрдП рд╢рдмреНрджрдХреЛрд╢ рдХреЛ рд╡рд╛рдкрд╕ рд▓реМрдЯрд╛рдПрдВред рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдЗрд╕реЗ рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рдорддрд▓рдм рдирд╣реАрдВ рд╣реИ, рдпрд╣ рд╕рд┐рд░реНрдл рдПрдХ рдЖрджрдд рд╣реИ :)



рд╣рдо рдЕрддрд┐рд░рд┐рдХреНрдд рдкреИрд░рд╛рдореАрдЯрд░ __annotations__



рдФрд░ рдбреЗрдХреЛрд░реЗрдЯрд░реНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП рдХрд╛рдлреА рд╕рдХреНрд░рд┐рдп рд╣реИрдВред рдЗрд╕рд▓рд┐рдП, рд╕рдорд╕реНрдпрд╛рдУрдВ рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдорд╛рдирдХ wraps



рдХреЛ рдкреВрд░рдХ рдХрд░рдирд╛ рдмреЗрд╣рддрд░ рд╣реЛрдЧрд╛ред



 from functools import wraps as orig_wraps, WRAPPER_ASSIGNMENTS WRAPPER_ASSIGNMENTS += ('__annotations__',) wraps = lambda x: orig_wraps(x, WRAPPER_ASSIGNMENTS)
      
      







рдЕрдм рд╣рдореЗрдВ рд▓рдХреНрд╖реНрдп рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рд▓рдкреЗрдЯрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдбреЗрдХреЛрд░реЗрдЯрд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЗрд╕реЗ рдПрдХ рд╡рд░реНрдЧ рдХреЗ рд░реВрдк рдореЗрдВ рдмрдирд╛рддреЗ рд╣реИрдВред рдпрд╣ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдЖрд╕рд╛рди рд╣реЛ рдЬрд╛рдПрдЧрд╛ред



 class Endpoint(object): """              >>> plus = Endpoint(plus) >>> plus(5.0, "4") 9 """ def __call__(self, *args, **kwargs): return self.callable(*args, **kwargs) def __init__(self, func): self.__annotations__ = func.__annotations__ self.__name__ = func.__name__ self.set_func(func) def set_func(self, func): if func.__annotations__: #       self.parser = Parser(func.__annotations__) #     . #     ,  #   self.callable = self._wrap_callable(func) else: self.callable = func def _wrap_callable(self, func): @wraps(func) def wrapper(*args, **kwargs): #    ,  #   ,     . #   -       #     return func(*args, **self.parser(kwargs)) return wrapper
      
      







рдЦреИрд░, рд╕рдм рдХреБрдЫ рддреИрдпрд╛рд░ рд╣реИред рдЗрд╕ рдмрд╛рдд рдХреЛ рдлреНрд▓рд╛рд╕реНрдХ рдХреЛ рдкреЗрдВрдЪ рдХрд░рдиреЗ рдХрд╛ рд╕рдордп рд╣реИред

рд╡реИрд╕реЗ, рдЗрд╕ рдмрд┐рдВрджреБ рдкрд░ рд╣рдордиреЗ рдЬреЛ рдХреБрдЫ рднреА рджреЗрдЦрд╛, рд╡рд╣ рд╕рдорд╛рди рд░реВрдк рд╕реЗ рдкрд░реНрдпрд╛рдкреНрдд рд╣реИ рддрд╛рдХрд┐ рдЕрдиреНрдп рд░реВрдкрд░реЗрдЦрд╛рдУрдВ рдореЗрдВ рд╕рдорд╛рди рдХреЛрдб рдЯреБрдХрдбрд╝реЗ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХреЗред рдФрд░ рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЗ рдмрд┐рдирд╛ рднреА :)



рдЪрд▓рд┐рдП рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ:

 class Flask(OrigFlask): #   .    froute = OrigFlask.route def route(self, rule, **options): """     . """ def registrator(func): #    : 1  - 1 . if 'methods' in options: method = options['methods'][0] else: method = 'GET' wrapped = self.register_endpoint(rule, func, options.get('name'), method) return wrapped return registrator def register_endpoint(self, rule, func, endpoint_name=None, method='GET'): endpoint_name = endpoint_name or func.__name__ endpoint = Endpoint(func) wrapped = self._arg_taker(endpoint) self.add_url_rule(rule, "%s.%s" % (endpoint_name, method), wrapped, methods=[method]) return wrapped def _arg_taker(self, func): """       .  . """ @wraps(func) def wrapper(*args, **kwargs): for key_name in func.__annotations__.keys(): kwargs[key_name] = request.args.get(key_name) return func(*args, **kwargs) return wrapper
      
      







рдорд╣рд╛рди, рдмреБрдирд┐рдпрд╛рджреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХрд╛рдо рдХрд░рддреА рд╣реИред рдЕрдм рддрдХ _from рдХреЗ рдмрд┐рдирд╛, рд▓реЗрдХрд┐рди, рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ, рдЕрдм рдЖрдк рдЗрд╕рдХреЗ рдмрд┐рдирд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред



рд╢рд▓рдЬрдо



рдЖрдк рдЕрдкрдиреЗ рдкреНрд░рд╢реНрди рдкреВрдЫ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░ рдХреА рд╕реБрд╡рд┐рдзрд╛рдПрдБ рдкреНрд░рджрд╛рди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рдЦрд░рд╛рдм рд╣реЛ рд╕рдХрддреА рд╣реИрдВред



рдпреБрдкреАрдбреА



рдЗрд╕ рдЧрд░реНрднрдирд┐рд░реЛрдзрдХ рдХреЗ рдЙрдкрдпреЛрдЧ рдкрд░ рдПрдХ рдЫреЛрдЯреА рдкреБрд╕реНрддрд┐рдХрд╛ рд▓рд┐рдЦреАред



All Articles