def logged(time_format):
def decorator(func):
def decorated_func(*args, **kwargs):
print "- Running '%s' on %s " % (
func.__name__,
time.strftime(time_format)
)
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print "- Finished '%s', execution time = %0.3fs " % (
func.__name__,
end_time - start_time
)
return result
decorated_func.__name__ = func.__name__
return decorated_func
return decorator
@logged("%b %d %Y - %H:%M:%S")
def add1(x, y):
time.sleep(1)
return x + y
@logged("%b %d %Y - %H:%M:%S")
def add2(x, y):
time.sleep(2)
return x + y
print add1(1, 2)
print add2(1, 2)
# Output:
- Running 'add1' on Jul 24 2013 - 13:40:47
- Finished 'add1', execution time = 1.001s
3
- Running 'add2' on Jul 24 2013 - 13:40:48
- Finished 'add2', execution time = 2.001s
3
import time
from functools import wraps
def cached(timeout, logged=False):
"""Decorator to cache the result of a function call.
Cache expires after timeout seconds.
"""
def decorator(func):
if logged:
print "-- Initializing cache for", func.__name__
cache = {}
@wraps(func)
def decorated_function(*args, **kwargs):
if logged:
print "-- Called function", func.__name__
key = (args, frozenset(kwargs.items()))
result = None
if key in cache:
if logged:
print "-- Cache hit for", func.__name__, key
(cache_hit, expiry) = cache[key]
if time.time() - expiry < timeout:
result = cache_hit
elif logged:
print "-- Cache expired for", func.__name__, key
elif logged:
print "-- Cache miss for", func.__name__, key
# No cache hit, or expired
if result is None:
result = func(*args, **kwargs)
cache[key] = (result, time.time())
return result
return decorated_function
return decorator
来看看它的用法。我们使用装饰器装饰一个很基本的斐波拉契数生成器。这个cache装饰器将对代码使用备忘录模式(Memoize Pattern)。请注意fib函数的闭包是如何存放cache字典、一个指向原fib函数的引用、logged参数的值以及timeout参数的最后值的。dump_closure将在文末定义。
>>> @cached(10, True)
... def fib(n):
... """Returns the n'th Fibonacci number."""
... if n == 0 or n == 1:
... return 1
... return fib(n - 1) + fib(n - 2)
...
-- Initializing cache for fib
>>> dump_closure(fib)
1. Dumping function closure for fib:
-- cell 0 = {}
-- cell 1 =
-- cell 2 = True
-- cell 3 = 10
>>>
>>> print "Testing - F(4) = %d" % fib(4)
-- Called function fib
-- Cache miss for fib ((4,), frozenset([]))
-- Called function fib
-- Cache miss for fib ((3,), frozenset([]))
-- Called function fib
-- Cache miss for fib ((2,), frozenset([]))
-- Called function fib
-- Cache miss for fib ((1,), frozenset([]))
-- Called function fib
-- Cache miss for fib ((0,), frozenset([]))
-- Called function fib
-- Cache hit for fib ((1,), frozenset([]))
-- Called function fib
-- Cache hit for fib ((2,), frozenset([]))
Testing - F(4) = 5
Class Decorators
def make_dual(relation):
@wraps(relation, ['__name__', '__doc__'])
def dual(x, y):
return relation(y, x)
return dual
def dual_ordering(cls):
"""Class decorator that reverses all the orderings"""
for func in ['__lt__', '__gt__', '__ge__', '__le__']:
if hasattr(cls, func):
setattr(cls, func, make_dual(getattr(cls, func)))
return cls
@dual_ordering
class rstr(str):
pass
x = rstr("1")
y = rstr("2")
print x < y
print x <= y
print x > y
print x >= y
# Output:
False
False
True
True
def logged(time_format, name_prefix=""):
def decorator(func):
if hasattr(func, '_logged_decorator') and func._logged_decorator:
return func
@wraps(func)
def decorated_func(*args, **kwargs):
start_time = time.time()
print "- Running '%s' on %s " % (
name_prefix + func.__name__,
time.strftime(time_format)
)
result = func(*args, **kwargs)
end_time = time.time()
print "- Finished '%s', execution time = %0.3fs " % (
name_prefix + func.__name__,
end_time - start_time
)
return result
decorated_func._logged_decorator = True
return decorated_func
return decorator
def log_method_calls(time_format):
def decorator(cls):
for o in dir(cls):
if o.startswith('__'):
continue
a = getattr(cls, o)
if hasattr(a, '__call__'):
decorated_a = logged(time_format, cls.__name__ + ".")(a)
setattr(cls, o, decorated_a)
return cls
return decorator
@log_method_calls("%b %d %Y - %H:%M:%S")
class A(object):
def test1(self):
print "test1"
@log_method_calls("%b %d %Y - %H:%M:%S")
class B(A):
def test1(self):
super(B, self).test1()
print "child test1"
def test2(self):
print "test2"
b = B()
b.test1()
b.test2()
# Output:
- Running 'B.test1' on Jul 24 2013 - 14:15:03
- Running 'A.test1' on Jul 24 2013 - 14:15:03
test1
- Finished 'A.test1', execution time = 0.000s
child test1
- Finished 'B.test1', execution time = 1.001s
- Running 'B.test2' on Jul 24 2013 - 14:15:04
test2
- Finished 'B.test2', execution time = 2.001s
def setupmethod(f):
"""Wraps a method so that it performs a check in debug mode if the
first request was already handled.
"""
def wrapper_func(self, *args, **kwargs):
if self.debug and self._got_first_request:
raise AssertionError('A setup function was called after the '
'first request was handled. This usually indicates a bug '
'in the application where a module was not imported '
'and decorators or other functionality was called too late.n'
'To fix this make sure to import all your view modules, '
'database models and everything related at a central place '
'before the application starts serving requests.')
return f(self, *args, **kwargs)
return update_wrapper(wrapper_func, f)
def route(self, rule, **options):
"""A decorator that is used to register a view function for a
given URL rule. This does the same thing as :meth:`add_url_rule`
but is intended for decorator usage::
@app.route('/')
def index():
return 'Hello World'
For more information refer to :ref:`url-route-registrations`.
:param rule: the URL rule as string
:param endpoint: the endpoint for the registered URL rule. Flask
itself assumes the name of the view function as
endpoint
:param options: the options to be forwarded to the underlying
:class:`~werkzeug.routing.Rule` object. A change
to Werkzeug is handling of method options. methods
is a list of methods this rule should be limited
to (`GET`, `POST` etc.). By default a rule
just listens for `GET` (and implicitly `HEAD`).
Starting with Flask 0.6, `OPTIONS` is implicitly
added and handled by the standard request handling.
"""
def decorator(f):
endpoint = options.pop('endpoint', None)
self.add_url_rule(rule, endpoint, f, **options)
return f
return decorator
>>> def return_func_that_prints_s(s):
... def f():
... print s
... return f
...
>>> g = return_func_that_prints_s("Hello")
>>> h = return_func_that_prints_s("World")
>>> g()
Hello
>>> h()
World
>>> g is h
False
>>> h.__closure__
(,)
>>> print [str(c.cell_contents) for c in g.__closure__]
['Hello']
>>> print [str(c.cell_contents) for c in h.__closure__]
['World']
>>> def return_func_that_prints_list(z): ... def f(): ... print z ... return f ... >>> z = [1, 2] >>> g = return_func_that_prints_list(z) >>> g() [1, 2] >>> z.append(3) >>> g() [1, 2, 3] >>> z = [1] >>> g() [1, 2, 3]
def dump_closure(f):
if hasattr(f, "__closure__") and f.__closure__ is not None:
print "- Dumping function closure for %s:" % f.__name__
for i, c in enumerate(f.__closure__):
print "-- cell %d = %s" % (i, c.cell_contents)
else:
print " - %s has no closure!" % f.__name__
机械节能产品生产企业官网模板...
大气智能家居家具装修装饰类企业通用网站模板...
礼品公司网站模板
宽屏简约大气婚纱摄影影楼模板...
蓝白WAP手机综合医院类整站源码(独立后台)...苏ICP备2024110244号-2 苏公网安备32050702011978号 增值电信业务经营许可证编号:苏B2-20251499 | Copyright 2018 - 2025 源码网商城 (www.ymwmall.com) 版权所有