Skip to content

Instantly share code, notes, and snippets.

@myarik
Last active May 24, 2016 09:31
Show Gist options
  • Save myarik/b1acebf33dcc0eeecf8d to your computer and use it in GitHub Desktop.
Save myarik/b1acebf33dcc0eeecf8d to your computer and use it in GitHub Desktop.
import functools
def float_args_and_return(function):
@functools.wraps(function)
def wrapper(*args, **kwargs):
args = [float(arg) for arg in args]
return float(function(*args, **kwargs))
return wrapper
@float_args_and_return
def mean(first, second, *rest):
numbers = (first, second) + rest
return sum(numbers)/len(numbers)
def statically_typed(return_type = None, *types):
def decorator(function):
@functools.wraps(function)
def wrapper(*args, **kwargs):
if len(args) > len(types):
raise ValueError("too many arguments")
elif len(args) < len(types):
raise ValueError("too few arguments")
for i, (arg, type_) in enumerate(zip(args, types)):
if not isinstance(arg, type_):
raise ValueError("argument {} must be of type {}".format(i , type_.__name__))
result = function(*args, **kwargs)
if (return_type is not None and not isinstance(result, return_type)):
raise ValueError("return value must be of type {}".format(return_type.__name__))
return result
return wrapper
return decorator
# Method decorator
class ImportantStuff(object):
@time_this
def do_stuff_1(self):
...
@time_this
def do_stuff_2(self):
...
@time_this
def do_stuff_3(self):
...
def time_this(original_function):
print "decorating"
def new_function(*args,**kwargs):
print "starting timer"
import datetime
before = datetime.datetime.now()
x = original_function(*args,**kwargs)
after = datetime.datetime.now()
print "Elapsed Time = {0}".format(after-before)
return x
return new_function
# Class decorator
@time_all_class_methods
class ImportantStuff:
def do_stuff_1(self):
...
def do_stuff_2(self):
...
def do_stuff_3(self):
...
ImportantStuff = time_all_class_methods(ImportantStuff)
def time_all_class_methods(Cls):
class NewCls(object):
def __init__(self,*args,**kwargs):
self.oInstance = Cls(*args,**kwargs)
def __getattribute__(self,s):
"""
this is called whenever any attribute of a NewCls object is accessed. This function first tries to
get the attribute off NewCls. If it fails then it tries to fetch the attribute from self.oInstance (an
instance of the decorated class). If it manages to fetch the attribute from self.oInstance, and
the attribute is an instance method then `time_this` is applied.
"""
try:
x = super(NewCls,self).__getattribute__(s)
except AttributeError:
pass
else:
return x
x = self.oInstance.__getattribute__(s)
if type(x) == type(self.__init__): # it is an instance method
return time_this(x) # this is equivalent of just decorating the method with time_this
else:
return x
return NewCls
# Define the validation wrapper
def ensure(name, validate, doc=None):
def decorator(Class):
privateName = "__" + name
def getter(self):
return getattr(self, privateName)
def setter(self, value):
validate(name, value)
setattr(self, privateName, value)
setattr(Class, name, property(getter, setter, doc=doc))
return Class
return decorator
@ensure("url", is_str)
class Person(object):
def http_methods(methods=[]):
"""
Данный декоратор проверяет метод HTTP запроса,
который пришел на вью, перед тем как
она будет вызвана.
Удобен тем, что можно задать набор HTTP слов,
на которые вьюха будет реагировать. В противном случае Http404.
"""
def decorator(func):
def wrapper(request, *args, **kwargs):
if request.method in methods:
view = func(request, *args, **kwargs)
return view
raise Http404
return wrapper
return decorator
#...
@http_methods(methods=['POST', 'GET'])
def your_view(request, *args, **kwargs):
pass
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment