def myDec(oldFunc): """ A decorator. """ def newFunc(*args, **kwargs): return "newFunc", oldFunc(*args, **kwargs) return finalizeWrapper(oldFunc, newFunc, "myDec")
def clipboardPreserving(function): """ A decorator which pushes the clipboard state before running the function, and pops it afterwards, whether or not the function raises an error. """ def wrapperFunc(*args, **kwargs): pushState() try: result = function(*args, **kwargs) finally: popState() return result return finalizeWrapper(function, wrapperFunc, "clipboardPreserving")
def clipboardDependent(function): """ A decorator which opens the clipboard before executing the wrapped function, then closes it when the wrapped function is done, whether or not the wrapped function throws an exception. """ def wrapperFunc(*args, **kwargs): # If safeOpenClipboard() raises an exception, this function will do # nothing but allow it to be raised. (We shouldn't attempt to close # the clipboard if we couldn't open it in the first place.) safeOpenClipboard() try: result = function(*args, **kwargs) finally: # If function raises an exception, the finally clause # will be executed and then the exception will be re-raised. safeCloseClipboard() return result return finalizeWrapper(function, wrapperFunc, "clipboardDependent")
def clipboardDependent( function ): """ A decorator which opens the clipboard before executing the wrapped function, then closes it when the wrapped function is done, whether or not the wrapped function throws an exception. """ def wrapperFunc( *args, **kwargs ): # If safeOpenClipboard() raises an exception, this function will do # nothing but allow it to be raised. (We shouldn't attempt to close # the clipboard if we couldn't open it in the first place.) safeOpenClipboard() try: result = function( *args, **kwargs ) finally: # If function raises an exception, the finally clause # will be executed and then the exception will be re-raised. safeCloseClipboard() return result return finalizeWrapper( function, wrapperFunc, "clipboardDependent" )
def memoized(function): """ 'Memoizes' the function, causing its results to be cached based on the called arguments. When subsequent calls to function are made using the same arguments, the cached value is returned rather than calling the function to re-compute the result. For instance: >>> timesCalled = 0 >>> @memoized ... def addNumbers( a, b ): ... global timesCalled ... timesCalled += 1 ... return a + b We can show that the above function is only called once for each unique pair of arguments like so: >>> addNumbers( 50, 20 ) 70 >>> timesCalled 1 >>> addNumbers( a=50, b=20 ) 70 >>> timesCalled 1 Using different arguments calls the function again, of course: >>> addNumbers( 20, 50 ) 70 >>> timesCalled 2 The memoized function cannot take any arguments that are non-hashable; this means that the memoized function cannot take dicts or lists, among others. For instance: >>> @memoized ... def myFunc( myDict ): ... myDict.update( {'bar':2} ) ... return myDict >>> myFunc( {'foo':1} ) Traceback (most recent call last): ... TypeError: dict objects are unhashable The memoized function also cannot take a ** argument, since this constitutes a dict. This decorator should only be used on functions which have a small number of relatively simple input arguments, and which are called a fantastic number of times. The memoized decorator is most effective in helping performance when used on factory functions, as the instantiated object (assuming that it should only be instantiated once) can be reused rather than re-instantiated (effectively providing the services of a flyweight pool). """ mfWrap = _MemoizedFunction(function) # For efficiency purposes, let's make it as easy to look up # mfWrap.cache as possible. cache = mfWrap.cache def memoizedFunctionWrapper(*args): # We're using a try-except clause here instead of testing # whether the dictionary has a key because we believe that it # is more efficient; it's preferable to speed up the most # common scenario where a cached value already exists by # simply assuming that it *does* exist. try: return cache[args] except KeyError: cache[args] = function(*args) return cache[args] finalWrapper = _generateArgWrapper(function, memoizedFunctionWrapper) return finalizeWrapper(function, finalWrapper, "Memoized")
def memoized( function ): """ 'Memoizes' the function, causing its results to be cached based on the called arguments. When subsequent calls to function are made using the same arguments, the cached value is returned rather than calling the function to re-compute the result. For instance: >>> timesCalled = 0 >>> @memoized ... def addNumbers( a, b ): ... global timesCalled ... timesCalled += 1 ... return a + b We can show that the above function is only called once for each unique pair of arguments like so: >>> addNumbers( 50, 20 ) 70 >>> timesCalled 1 >>> addNumbers( a=50, b=20 ) 70 >>> timesCalled 1 Using different arguments calls the function again, of course: >>> addNumbers( 20, 50 ) 70 >>> timesCalled 2 The memoized function cannot take any arguments that are non-hashable; this means that the memoized function cannot take dicts or lists, among others. For instance: >>> @memoized ... def myFunc( myDict ): ... myDict.update( {'bar':2} ) ... return myDict >>> myFunc( {'foo':1} ) Traceback (most recent call last): ... TypeError: dict objects are unhashable The memoized function also cannot take a ** argument, since this constitutes a dict. This decorator should only be used on functions which have a small number of relatively simple input arguments, and which are called a fantastic number of times. The memoized decorator is most effective in helping performance when used on factory functions, as the instantiated object (assuming that it should only be instantiated once) can be reused rather than re-instantiated (effectively providing the services of a flyweight pool). """ mfWrap = _MemoizedFunction( function ) # For efficiency purposes, let's make it as easy to look up # mfWrap.cache as possible. cache = mfWrap.cache def memoizedFunctionWrapper( *args ): # We're using a try-except clause here instead of testing # whether the dictionary has a key because we believe that it # is more efficient; it's preferable to speed up the most # common scenario where a cached value already exists by # simply assuming that it *does* exist. try: return cache[args] except KeyError: cache[args] = function( *args ) return cache[args] finalWrapper = _generateArgWrapper( function, memoizedFunctionWrapper ) return finalizeWrapper( function, finalWrapper, "Memoized" )