Commits

Jason R. Coombs committed cd153b4

Added functools.once

Comments (0)

Files changed (2)

 Changes
 -------
 
+5.1
+~~~
+
+* Added `functools.once`, a rudimentary caching function to ensure an
+  expensive or non-idempotent function is not expensive on subsequent calls
+  and is idempotent.
+
 5.0
 ~~~
 

jaraco/util/functools.py

 from __future__ import absolute_import, unicode_literals
-from functools import reduce
+
+import functools
 
 def compose(*funcs):
 	"""
 	"""
 
 	compose_two = lambda f1, f2: lambda v: f1(f2(v))
-	return reduce(compose_two, funcs)
+	return functools.reduce(compose_two, funcs)
 
 def method_caller(method_name, *args, **kwargs):
 	"""
 		func = getattr(target, method_name)
 		return func(*args, **kwargs)
 	return call_method
+
+def once(func):
+	"""
+	Decorate func so it's only ever called the first time.
+
+	This decorator can ensure that an expensive or non-idempotent function
+	will not be expensive on subsequent calls and is idempotent.
+
+	>>> func = once(lambda a: a+3)
+	>>> func(3)
+	6
+	>>> func(9)
+	6
+	>>> func('12')
+	6
+	"""
+	@functools.wraps(func)
+	def wrapper(*args, **kwargs):
+		if not hasattr(func, 'always_returns'):
+			func.always_returns = func(*args, **kwargs)
+		return func.always_returns
+	return wrapper