>>> from functools import wraps >>> def log_errors(func): ... @wraps(func) ... def log_errors_wrapper(*args, **kwargs): ... try: ... return func(*args, **kwargs) ... except Exception as exc: ... print("Raised %r for %s/%s" % (exc, args, kwargs)) ... raise ... return log_errors_wrapper >>> @log_errors ... def broken_function(): ... raise RuntimeError() >>> from pytest import raises >>> raises(RuntimeError, broken_function) Raised RuntimeError() for ()/{} ...
def log_errors(func): def wrapper(*args, **kwargs): try: return func(*args, **kwargs) except Exception as exc: print("Raised %r for %s/%s" % (exc, args, kwargs)) raise exc return wrapper
Există 2 tipuri de funcții, decise la compilare:
Așadar, funcția generator intoarce un generator.
>>> @log_errors ... def broken_generator(): ... yield 1 ... raise RuntimeError() >>> _=raises(RuntimeError, lambda: list(broken_generator()))
Dooh ! Nu se intampla nimic ...
>>> from inspect import isgeneratorfunction >>> def log_errors(func): ... if isgeneratorfunction(func): ... @wraps(func) ... def log_errors_wrapper(*args, **kwargs): ... try: ... for item in func(*args, **kwargs): ... yield item ... except Exception as exc: ... print("Raised %r for %s/%s" % (exc, args, kwargs)) ... raise ... else: ... @wraps(func) ... def log_errors_wrapper(*args, **kwargs): ... try: ... return func(*args, **kwargs) ... except Exception as exc: ... print("Raised %r for %s/%s" % (exc, args, kwargs)) ... raise ... return log_errors_wrapper
>>> @log_errors ... def broken_generator(): ... yield 1 ... raise RuntimeError() >>> raises(RuntimeError, list, broken_generator()) Raised RuntimeError() for ()/{} ...
def
>>> from aspectlib import Aspect >>> @Aspect ... def log_errors(*args, **kwargs): ... try: ... yield ... except Exception as exc: ... print("Raised %r for %s/%s" % (exc, args, kwargs)) ... raise
Works as expected with generators:
>>> @log_errors ... def broken_generator(): ... yield 1 ... raise RuntimeError() >>> raises(RuntimeError, lambda: list(broken_generator())) Raised RuntimeError() for ()/{} ... >>> @log_errors ... def broken_function(): ... raise RuntimeError() >>> raises(RuntimeError, broken_function) Raised RuntimeError() for ()/{} ...
This presentation:
https://github.com/ionelmc/python-aspectlib/tree/master/docs/presentations
aspectlib does many more things, check it out:
Table of Contents | t |
---|---|
Exposé | ESC |
Full screen slides | e |
Presenter View | p |
Source Files | s |
Slide Numbers | n |
Toggle screen blanking | b |
Show/hide slide context | c |
Notes | 2 |
Help | h |