Advertisement
Woobinda

Static types decorator; Class @decorator

May 11th, 2018
261
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.07 KB | None | 0 0
  1. def statically_typed(*types, return_type=None):
  2.     def decorator(function):
  3.         @functools.wraps(function)
  4.         def wrapper(*args, **kwargs):
  5.             if len(args) > len(types):
  6.                 raise ValueError('too many arguments')
  7.             if len(args) < len(types):
  8.                 raise ValueError('too few arguments')
  9.             for i, (arg, type_) in enumerate(zip(args, types)):
  10.                 if not isinstance(arg, type_):
  11.                     raise ValueError('argument {} must be of type {}'
  12.                              .format(i, type_.__name__))
  13.             result = function(*args, **kwargs)
  14.             if (return_type is not None and not isinstance(result, return_type)):
  15.                 raise ValueError('return value must be of type {}'.format(return_type.__name__))
  16.             return result
  17.         return wrapper
  18.     return decorator
  19.  
  20. Examples:
  21. @statically_typed(str, int, str)
  22. def repeat(what, count, separator):
  23.     return ((what + separator) * count)[:-len(separator)]
  24.  
  25. @statically_typed(str, str, return_type=str)
  26. def make_tagged(text, tag):
  27.     return '<{0}>{1}</{0}>'.format(tag, text)
  28.  
  29. ---------------
  30. Class decorator
  31. ---------------
  32.  
  33. def do_ensure(Class):
  34.     def make_property(name, attribute):
  35.         privateName = "__" + name
  36.         def getter(self):
  37.             return getattr(self, privateName)
  38.         def setter(self, value):
  39.             attribute.validate(name, value)
  40.             return setattr(self, privateName, value)
  41.         return property(getter, setter, doc=attribute.doc)
  42.     for name, attribute in Class.__dict__.items():
  43.         if isinstance(attribute, Ensure):
  44.             setattr(Class, name, make_property(name, attribute))
  45.     return Class
  46.  
  47. class Ensure:
  48.     def __init__(self, validate, doc=None):
  49.         self.validate = validate
  50.         self.doc = doc
  51.  
  52. def is_non_empty_str(name, value):
  53.     if not isinstance(value, str):
  54.         raise ValueError('must be str')
  55.     if not bool(value):
  56.         raise ValueError('may not be empty')
  57.  
  58. Example:
  59. @do_ensure
  60. class Book:
  61.     title = Ensure(is_non_empty_str)
  62.     author = Ensure(is_non_empty_str)
  63.     def __init__(self, title, author):
  64.         self.title = title
  65.         self.author = author
  66.     @property
  67.     def value(self):
  68.         return 'Title: %s. Author: %s' % (self.title, self.author)
  69.  
  70. book = Book('Some title', 'First Name, Last Name')
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement