def _method_magic_marker(magic_kind):
"""Decorator factory for methods in Magics subclasses.
"""
validate_type(magic_kind)
# This is a closure to capture the magic_kind. We could also use a class,
# but it's overkill for just that one bit of state.
def magic_deco(arg):
call = lambda f, *a, **k: f(*a, **k)
if callable(arg):
# "Naked" decorator call (just @foo, no args)
func = arg
name = func.__name__
retval = decorator(call, func)
record_magic(magics, magic_kind, name, name)
elif isinstance(arg, str):
# Decorator called with arguments (@foo('bar'))
name = arg
def mark(func, *a, **kw):
record_magic(magics, magic_kind, name, func.__name__)
return decorator(call, func)
retval = mark
else:
raise TypeError("Decorator can only be called with "
"string or function")
return retval
# Ensure the resulting decorator has a usable docstring
magic_deco.__doc__ = _docstring_template.format('method', magic_kind)
return magic_deco
python类decorator()的实例源码
def register(self, *magic_objects):
"""Register one or more instances of Magics.
Take one or more classes or instances of classes that subclass the main
`core.Magic` class, and register them with IPython to use the magic
functions they provide. The registration process will then ensure that
any methods that have decorated to provide line and/or cell magics will
be recognized with the `%x`/`%%x` syntax as a line/cell magic
respectively.
If classes are given, they will be instantiated with the default
constructor. If your classes need a custom constructor, you should
instanitate them first and pass the instance.
The provided arguments can be an arbitrary mix of classes and instances.
Parameters
----------
magic_objects : one or more classes or instances
"""
# Start by validating them to ensure they have all had their magic
# methods registered at the instance level
for m in magic_objects:
if not m.registered:
raise ValueError("Class of magics %r was constructed without "
"the @register_magics class decorator")
if isinstance(m, type):
# If we're given an uninstantiated class
m = m(shell=self.shell)
# Now that we have an instance, we can register it and update the
# table of callables
self.registry[m.__class__.__name__] = m
for mtype in magic_kinds:
self.magics[mtype].update(m.magics[mtype])
def apply_wrapper(wrapper, func):
"""Apply a wrapper to a function for decoration.
This mixes Michele Simionato's decorator tool with nose's make_decorator,
to apply a wrapper in a decorator so that all nose attributes, as well as
function signature and other properties, survive the decoration cleanly.
This will ensure that wrapped functions can still be well introspected via
IPython, for example.
"""
warnings.warn("The function `apply_wrapper` is deprecated since IPython 4.0",
DeprecationWarning, stacklevel=2)
import nose.tools
return decorator(wrapper,nose.tools.make_decorator(func)(wrapper))
def module_not_available(module):
"""Can module be imported? Returns true if module does NOT import.
This is used to make a decorator to skip tests that require module to be
available, but delay the 'import numpy' to test execution time.
"""
try:
mod = import_module(module)
mod_not_avail = False
except ImportError:
mod_not_avail = True
return mod_not_avail
def icache(f):
f.cache = {}
return decorator.decorator(_icache,f)
def indicator(f):
f.storage = {}
aspecs = getargspec(f).args
f.tpos = aspecs.index('_ts')
assert f.tpos == len(aspecs)-1,'position of _ts is invalid' #_ts?????????????
return decorator.decorator(_indicator,f)
##############
# ????
# ???ma
##############
#@icache
def aop_check_session(f):
"""
CherryPy-specific session checking decorator.
:param f: the function
"""
return decorator(_check_session_aspect, f)
def aop_login_json(f):
"""
CherryPy-specific session login decorator.
"""
return decorator(_login_json_aspect, f)
def aop_check_session(f):
"""
A session validation decorator, searches that parameters for _session_id and checks that session
"""
return decorator(check_session_aspect, f)
def not_implemented(f):
"""
Raises a NotImplementedError error. Example: "Internal error in function_name: Not implemented."
"""
return decorator(_not_implemented, f)
def decorator(w):
"""
The C{decorator} module was not found. You can install it from:
U{http://pypi.python.org/pypi/decorator/}
"""
def d(fn):
@functools.wraps(fn)
def x(*argv, **argd):
return w(fn, *argv, **argd)
return x
return d
#------------------------------------------------------------------------------
def __call__(self, f):
"""
Method call wrapper. As this decorator has arguments, this method will
only be called once as a part of the decoration process, receiving only
one argument: the decorated function ('f'). As a result of this kind of
decorator, this method must return the callable that will wrap the
decorated function.
"""
if isinstance(f, property):
f.fget._aliases = self.aliases
else:
f._aliases = self.aliases
return f
def apply_to_mask(f, clip, *a, **k):
""" This decorator will apply the same function f to the mask of
the clip created with f """
newclip = f(clip, *a, **k)
if hasattr(newclip, 'mask') and (newclip.mask is not None):
newclip.mask = f(newclip.mask, *a, **k)
return newclip
def apply_to_audio(f, clip, *a, **k):
""" This decorator will apply the function f to the audio of
the clip created with f """
newclip = f(clip, *a, **k)
if hasattr(newclip, 'audio') and (newclip.audio is not None):
newclip.audio = f(newclip.audio, *a, **k)
return newclip
def audio_video_fx(f, clip, *a, **k):
""" Use an audio function on a video/audio clip
This decorator tells that the function f (audioclip -> audioclip)
can be also used on a video clip, at which case it returns a
videoclip with unmodified video and modified audio.
"""
if hasattr(clip, "audio"):
newclip = clip.copy()
if clip.audio is not None:
newclip.audio = f(clip.audio, *a, **k)
return newclip
else:
return f(clip, *a, **k)
def decorator(w):
"""
The C{decorator} module was not found. You can install it from:
U{http://pypi.python.org/pypi/decorator/}
"""
def d(fn):
@functools.wraps(fn)
def x(*argv, **argd):
return w(fn, *argv, **argd)
return x
return d
#------------------------------------------------------------------------------
def cache_disk(function):
""" Lazy evaluation of function, by storing the results to the disk,
and not rerunning the function twice for the same arguments.
It works by explicitly saving the output to a file and it is
designed to work with non-hashable and potentially large input
and output data types such as numpy arrays
Note
----
Any change in the function code will result re-cache
Example
-------
>>> import numpy as np
>>> @cache_memory
>>> def doit(x):
... y = np.random.rand(1208, 1208)
... print("Function called:", np.sum(y))
... return y
>>> for _ in range(12):
... print(np.sum(doit(8)))
"""
def decorator_apply(dec, func):
"""Decorate a function by preserving the signature even if dec
is not a signature-preserving decorator.
This recipe is derived from
http://micheles.googlecode.com/hg/decorator/documentation.html#id14
"""
return FunctionMaker.create(
func, 'return decorated(%(signature)s)',
dict(decorated=dec(func)), __wrapped__=func)
return decorator_apply(__memory.cache, function)
# ===========================================================================
# Cache
# ===========================================================================
def authorize(authorizer):
"""Constructs authorizer decorator."""
@decorator.decorator
def decorated(func, *args, **kwargs):
"""Decorated function."""
action = getattr(func, 'auth_action', func.__name__.strip('_'))
resource = getattr(func, 'auth_resource', func.__module__.strip('_'))
_LOGGER.debug('Authorize: %s %s %r %r', resource, action, args, kwargs)
authorizer.authorize(resource, action, args, kwargs)
return func(*args, **kwargs)
return decorated
def validate_type(magic_kind):
"""Ensure that the given magic_kind is valid.
Check that the given magic_kind is one of the accepted spec types (stored
in the global `magic_spec`), raise ValueError otherwise.
"""
if magic_kind not in magic_spec:
raise ValueError('magic_kind must be one of %s, %s given' %
magic_kinds, magic_kind)
# The docstrings for the decorator below will be fairly similar for the two
# types (method and function), so we generate them here once and reuse the
# templates below.
def _method_magic_marker(magic_kind):
"""Decorator factory for methods in Magics subclasses.
"""
validate_type(magic_kind)
# This is a closure to capture the magic_kind. We could also use a class,
# but it's overkill for just that one bit of state.
def magic_deco(arg):
call = lambda f, *a, **k: f(*a, **k)
if callable(arg):
# "Naked" decorator call (just @foo, no args)
func = arg
name = func.__name__
retval = decorator(call, func)
record_magic(magics, magic_kind, name, name)
elif isinstance(arg, string_types):
# Decorator called with arguments (@foo('bar'))
name = arg
def mark(func, *a, **kw):
record_magic(magics, magic_kind, name, func.__name__)
return decorator(call, func)
retval = mark
else:
raise TypeError("Decorator can only be called with "
"string or function")
return retval
# Ensure the resulting decorator has a usable docstring
magic_deco.__doc__ = _docstring_template.format('method', magic_kind)
return magic_deco