1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
|
""" Supplies the internal functions for functools.py in the standard library """
# reduce() has moved to _functools in Python 2.6+.
reduce = reduce
class partial(object):
"""
partial(func, *args, **keywords) - new function with partial application
of the given arguments and keywords.
"""
__slots__ = ('_func', '_args', '_keywords', '__dict__')
def __init__(*args, **keywords):
if len(args) < 2:
raise TypeError('__init__() takes at least 2 arguments (%d given)'
% len(args))
self, func, args = args[0], args[1], args[2:]
if not callable(func):
raise TypeError("the first argument must be callable")
self._func = func
self._args = args
self._keywords = keywords
def __delattr__(self, key):
if key == '__dict__':
raise TypeError("a partial object's dictionary may not be deleted")
object.__delattr__(self, key)
@property
def func(self):
return self._func
@property
def args(self):
return self._args
@property
def keywords(self):
return self._keywords
def __call__(self, *fargs, **fkeywords):
if self._keywords:
fkeywords = dict(self._keywords, **fkeywords)
return self._func(*(self._args + fargs), **fkeywords)
def __reduce__(self):
d = dict((k, v) for k, v in self.__dict__.iteritems() if k not in
('_func', '_args', '_keywords'))
if len(d) == 0:
d = None
return (type(self), (self._func,),
(self._func, self._args, self._keywords, d))
def __setstate__(self, state):
if not isinstance(state, tuple) or len(state) != 4:
raise TypeError("invalid partial state")
func, args, keywords, d = state
if (not callable(func) or not isinstance(args, tuple) or
(keywords is not None and not isinstance(keywords, dict))):
raise TypeError("invalid partial state")
self._func = func
self._args = tuple(args)
if keywords is None:
keywords = {}
elif type(keywords) is not dict:
keywords = dict(keywords)
self._keywords = keywords
if d is None:
self.__dict__.clear()
else:
self.__dict__.update(d)
|