Python 2.5c1 (r25c1:51305, Aug 17 2006, 10:41:11) [MSC v.1310 32 bit (Intel)] on win32 IDLE 1.2c1 >>> dir() ['__builtins__', '__doc__', '__name__'] >>> ================================ RESTART ================================ >>> >>> partial >>> partial.__doc__ 'partial(func, *args, **keywords) - new function with partial application\n\tof the given arguments and keywords.\n' >>> print _ partial(func, *args, **keywords) - new function with partial application of the given arguments and keywords. >>> help(wraps) Help on function wraps in module functools: wraps(wrapped, assigned=('__module__', '__name__', '__doc__'), updated=('__dict__',)) Decorator factory to apply update_wrapper() to a wrapper function Returns a decorator that invokes update_wrapper() with the decorated function as the wrapper argument and the arguments to wraps() as the remaining arguments. Default arguments are as for update_wrapper(). This is a convenience function to simplify applying partial() to update_wrapper(). >>> my_add = lambda x,y: x+y >>> my_add2 = partial(my_add) >>> my_add2() Traceback (most recent call last): File "", line 1, in my_add2() TypeError: () takes exactly 2 arguments (0 given) >>> my_add2(1,2) 3 >>> >>> >>> >>> >>> add = lambda x,y: x+y >>> import operator >>> add = operator.add >>> add >>> add(1,2) 3 >>> add(10,100) 110 >>> add("a","b") 'ab' >>> >>> #partial function application, before 2.5 >>> >>> add5 = lambda x: add(x,5) >>> add5(10) 15 >>> add5(20) 25 >>> add5(-5) 0 >>> >>> add10 = lambda x: add(x,10) >>> add10(10) 20 >>> >>> range_skip2 = lambda start, stop: range(start, stop, step=2) >>> range_skip2(10, 20) Traceback (most recent call last): File "", line 1, in range_skip2(10, 20) File "", line 1, in range_skip2 = lambda start, stop: range(start, stop, step=2) TypeError: range() takes no keyword arguments >>> range_skip2 = lambda start, stop: range(start, stop, 2) >>> range_skip2(10,20) [10, 12, 14, 16, 18] >>> range_skip3 = lambda start, stop: range(start, stop, 3) >>> >>> range_skip3(10, 100) [10, 13, 16, 19, 22, 25, 28, 31, 34, 37, 40, 43, 46, 49, 52, 55, 58, 61, 64, 67, 70, 73, 76, 79, 82, 85, 88, 91, 94, 97] >>> >>> >>> F = lambda x,y,z: x+y+z >>> F(1,2,3) 6 >>> f(10,10,10) Traceback (most recent call last): File "", line 1, in f(10,10,10) NameError: name 'f' is not defined >>> F(10,10,10) 30 >>> >>> F_curry = lambda x: lambda y: lambda z: F(x,y,z) >>> F_curry(10)(10)(10) 30 >>> 10+10+10 30 >>> partial >>> >>> >>> succ = partial(add, 5) >>> succ = partial(add, 1) >>> pred = partial(add, -1) >>> pred(pred(pred(0))) -3 >>> succ(0) 1 >>> succ(1) 2 >>> succ(2) 3 >>> import functools >>> dir(functools) ['WRAPPER_ASSIGNMENTS', 'WRAPPER_UPDATES', '__builtins__', '__doc__', '__file__', '__name__', 'partial', 'update_wrapper', 'wraps'] >>> print update_wrapper.__doc__ Traceback (most recent call last): File "", line 1, in print update_wrapper.__doc__ NameError: name 'update_wrapper' is not defined >>> print functools.update_wrapper.__doc__ Update a wrapper function to look like the wrapped function wrapper is the function to be updated wrapped is the original function assigned is a tuple naming the attributes assigned directly from the wrapped function to the wrapper function (defaults to functools.WRAPPER_ASSIGNMENTS) updated is a tuple naming the attributes off the wrapper that are updated with the corresponding attribute from the wrapped function (defaults to functools.WRAPPER_UPDATES) >>> functools.wraps >>> print functools.wraps.__doc__ Decorator factory to apply update_wrapper() to a wrapper function Returns a decorator that invokes update_wrapper() with the decorated function as the wrapper argument and the arguments to wraps() as the remaining arguments. Default arguments are as for update_wrapper(). This is a convenience function to simplify applying partial() to update_wrapper(). >>> >>> >>> partial >>> partial.__doc__ 'partial(func, *args, **keywords) - new function with partial application\n\tof the given arguments and keywords.\n' >>> print _ partial(func, *args, **keywords) - new function with partial application of the given arguments and keywords. >>> >>> >>> >>> add1 = partial(add, 1) >>> add1(1) 2 >>> add1(2) 3 >>> sub1 = partial(add, -1) >>> sub1(5) 4 >>> sub1(_) 3 >>> sub1.__doc__ 'partial(func, *args, **keywords) - new function with partial application\n\tof the given arguments and keywords.\n' >>> >>> >>> >>> import string >>> string.sep Traceback (most recent call last): File "", line 1, in string.sep AttributeError: 'module' object has no attribute 'sep' >>> split = string.split >>> >>> make_split = partial(partial, split) >>> make_split(",") >>> split_commas = make_split(",") >>> split_commas("1,2,3,4,5") [','] >>> string.split("blah", sep="a") ['bl', 'h'] >>> make_split = lambda sep: partial(split, sep=sep) >>> make_split(",")("1,2,2,3") ['1', '2', '2', '3'] >>> str = "??" Unsupported characters in input >>> make_adder = lambda x: partial(add, x) make+_ >>> make_adder(5)(10) 15 >>> >>> >>> >>> #before 2.5 >>> >>> add = lambda x,y: x+y >>> import operator >>> add = operator.add >>> >>> add5 = lambda x: add(5, x) >>> add5(10) 15 >>> add5(-5) 0 >>> add10 = lambda x: add(10, x) >>> def sub10(x): return add(-10, x) >>> sub10(10) 0 >>> >>> range(0, 10, step=2) Traceback (most recent call last): File "", line 1, in range(0, 10, step=2) TypeError: range() takes no keyword arguments >>> range(0, 10, 2) [0, 2, 4, 6, 8] >>> range_skip2 = lambda start,stop: range(start, stop, 2) >>> range_skip2(10, 100) [10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98] >>> >>> range_skip2 at 0x014105F0> >>> sub10 >>> add10 at 0x00BB48B0> >>> >>> add_triple = lambda x,y,z: x+y+z >>> add_triple(10,5,-1) 14 >>> >>> add_triple_curried = lambda x: lambda y: lambda z: add_triple(x,y,z) >>> add_triple_curried(1) at 0x014104B0> >>> f2 = _ >>> f2(1) at 0x01410430> >>> f3 = _ >>> f3(1) 3 >>> >>> from functools import partial >>> >>> succ = partial(add, 1) >>> pred = partial(add, 2) >>> succ(0) 1 >>> succ(succ(0)) 2 >>> succ(2) 3 >>> pred(3) 5 >>> pred(3) 5 >>> print partial.__doc__ partial(func, *args, **keywords) - new function with partial application of the given arguments and keywords. >>> >>> >>> range(0, 10, 2) [0, 2, 4, 6, 8] >>> range_skip2 = partial(range, skip=2) >>> range_skip2(10,100) Traceback (most recent call last): File "", line 1, in range_skip2(10,100) TypeError: range() takes no keyword arguments >>> class Car(object): def __init__(self, mfr, doors, color): self.mfr = mfr self.doors = doors self.color = color >>> Car(mfr="Ford", doors=4, color="Red") <__main__.Car object at 0x01411050> >>> c = _ >>> c.color 'Red' >>> >>> twodoors = partial(Car, doors=2) >>> TwoDoorCar(mfr="Ford", color="Red") Traceback (most recent call last): File "", line 1, in TwoDoorCar(mfr="Ford", color="Red") NameError: name 'TwoDoorCar' is not defined >>> TwoDoorCar = twodoors >>> TwoDoorCar(mfr="Ford", color="Red") <__main__.Car object at 0x01411E70> >>> c2 = _ >>> c2.doors 2 >>> c2.color 'Red' >>> c2.mfr 'Ford' >>> >>> >>> >>> >>> >>> >>> import string >>> string.split("1,2,3,4,5,6", sep=",") ['1', '2', '3', '4', '5', '6'] >>> splitcommas = partial(string.split, sep=",") >>> splitcommas("1,2,3,4,5,6") ['1', '2', '3', '4', '5', '6'] >>> splitspaces = partial(string.split, sep=" ") >>> splitspaces("Hello world, from Python 2.5") ['Hello', 'world,', 'from', 'Python', '2.5'] >>> >>> make_splitter = lambda sep: partial(string.split, sep=sep) >>> make_splitter(",") >>> make_splitter(",")("1,2,3,4,5") ['1', '2', '3', '4', '5'] >>> make_splitter("|")("1|2|3|4|5") ['1', '2', '3', '4', '5'] >>> split_bars = make_splitter("|") >>> split_bars("Hello|Earth") ['Hello', 'Earth'] >>> >>> >>> >>> say >>> say("Hello world") Hello world >>> say("Error: Don't panic", stream=sys.stdout) Error: Don't panic >>> say("Error: Don't panic", stream=sys.stderr) Error: Don't panic >>> say("Error: Don't panic", stream=file("c:/testoutput.txt")) Traceback (most recent call last): File "", line 1, in say("Error: Don't panic", stream=file("c:/testoutput.txt")) IOError: [Errno 2] No such file or directory: 'c:/testoutput.txt' >>> say("Error: Don't panic", stream=file("c:/testoutput.txt", "w")) >>> >>> say_stdout = partial(say, stream=stdout) Traceback (most recent call last): File "", line 1, in say_stdout = partial(say, stream=stdout) NameError: name 'stdout' is not defined >>> say_stdout = partial(say, stream=sys.stdout) >>> say_error = partial(say, stream=sys.stderr) >>> say_error("Error: blowing up now") Error: blowing up now >>> append_log = partial(say, stream=file("c:/testoutput.txt", "a")) >>> append_log("Hello world") >>> append_log("This is the third line") >>> >>> >>> def mydeco(f): print "Calling %s", f.__name__ return f >>> >>> >>> >>> @mydeco def factorial(n): if n < 0: return 1 else: return factorial(n-1) Calling %s factorial >>> factorial(10) 1 >>> factorial.__name__ 'factorial' >>> >>> def mydeco(f): def inner(*args, **kwargs): print "Calling decorated function %s" % f.__name__ return f(*args, **kwargs) return inner >>> >>> @mydeco def factorial(n): if n < 0: return 1 else: return n*factorial(n-1) >>> factorial(10) Calling decorated function factorial Calling decorated function factorial Calling decorated function factorial Calling decorated function factorial Calling decorated function factorial Calling decorated function factorial Calling decorated function factorial Calling decorated function factorial Calling decorated function factorial Calling decorated function factorial Calling decorated function factorial Calling decorated function factorial 0 >>> factorial(1) Calling decorated function factorial Calling decorated function factorial Calling decorated function factorial 0 >>> ================================ RESTART ================================ >>> >>> >>> >>> factorial(10) 0 >>> ================================ RESTART ================================ >>> >>> factorial(10) 3628800 >>> dec_factorial = mydeco(factorial) >>> dec_factorial(10) Traceback (most recent call last): File "", line 1, in dec_factorial(10) TypeError: 'NoneType' object is not callable >>> dec_factorial >>> ================================ RESTART ================================ >>> >>> dec_factorial = mydeco(factorial) >>> dec_factorial(10) Calling decorated factorial with args: (10,), {} 3628800 >>> ================================ RESTART ================================ >>> >>> help(factorial) Help on function factorial in module __main__: factorial(n) Test simple recursive factorial function (n!) >>> dec_factorial = mydeco(factorial) >>> help(dec_factorial) Help on function inner in module __main__: inner(*args, **kwargs) >>> ================================ RESTART ================================ >>> >>> factorial(10) Calling decorated factorial with args: (10,), {} Calling decorated factorial with args: (9,), {} Calling decorated factorial with args: (8,), {} Calling decorated factorial with args: (7,), {} Calling decorated factorial with args: (6,), {} Calling decorated factorial with args: (5,), {} Calling decorated factorial with args: (4,), {} Calling decorated factorial with args: (3,), {} Calling decorated factorial with args: (2,), {} Calling decorated factorial with args: (1,), {} Calling decorated factorial with args: (0,), {} 3628800 >>> factorial.__doc__ >>> import inspect >>> inspect.getargspec(factorial) ([], 'args', 'kwargs', None) >>> >>> better_factorial = wraps(factorial) >>> better_factorial.__doc__ 'partial(func, *args, **keywords) - new function with partial application\n\tof the given arguments and keywords.\n' >>> better_factorial(10) Traceback (most recent call last): File "", line 1, in better_factorial(10) File "C:\Python25\lib\functools.py", line 33, in update_wrapper setattr(wrapper, attr, getattr(wrapped, attr)) AttributeError: 'int' object has no attribute '__module__' >>> >>> >>> ================================ RESTART ================================ >>> >>> >>> factorial(10) Calling decorated factorial with args: (10,), {} Calling decorated factorial with args: (9,), {} Calling decorated factorial with args: (8,), {} Calling decorated factorial with args: (7,), {} Calling decorated factorial with args: (6,), {} Calling decorated factorial with args: (5,), {} Calling decorated factorial with args: (4,), {} Calling decorated factorial with args: (3,), {} Calling decorated factorial with args: (2,), {} Calling decorated factorial with args: (1,), {} Calling decorated factorial with args: (0,), {} 3628800 >>> factorial.__doc__ 'Test simple recursive factorial function (n!)' >>> factorial.__name__ 'factorial' >>> help(factorial) Help on function factorial in module __main__: factorial(*args, **kwargs) Test simple recursive factorial function (n!) >>> inspect.getargspec(factorial) Traceback (most recent call last): File "", line 1, in inspect.getargspec(factorial) NameError: name 'inspect' is not defined >>> import inspect >>> inspect.getargspec(factorial) ([], 'args', 'kwargs', None) >>> >>> >>> >>> >>> x = 20 >>> if x > 0: print "Positive"; else: print "Negative or zero"; SyntaxError: invalid syntax >>> if x > 0: print "Positive" else: print "Negative or Zero" Positive >>> >>> >>> >>> (x > 20) and "Positive" or "Negative or zero" 'Negative or zero' >>> (x > 20) and "Negative or zero" and "Positive" False >>> (x > 0) and "Positive" or "Negative or zero" 'Positive' >>> x = -10 >>> (x > 0) and "Positive" or "Negative or zero" 'Negative or zero' >>> >>> ["Negative or zero", "Positive"][x > 0] 'Negative or zero' >>> x = 20 >>> ["Negative or zero", "Positive"][x > 0] 'Positive' >>> int(x>0) 1 >>> int(False) 0 >>> ["Division by zero", 10/x][x != 0] 0 >>> ["Division by zero", 10.0/x][x != 0] 0.5 >>> x = 0 >>> ["Division by zero", 10.0/x][x != 0] Traceback (most recent call last): File "", line 1, in ["Division by zero", 10.0/x][x != 0] ZeroDivisionError: float division >>> >>> >>> "Division by zero" if x == 0 else 10.0/x 'Division by zero' >>> x = 100 >>> "Division by zero" if x == 0 else 10.0/x 0.10000000000000001 >>> >>> >>> temperature = 45 >>> "Above freezing" if temperature > 32 else ("At freezing" if temperature == 32 else "Below freezing") 'Above freezing' >>> temperature = 32 >>> "Above freezing" if temperature > 32 else ("At freezing" if temperature == 32 else "Below freezing") 'At freezing' >>> temperature = 12 >>> "Above freezing" if temperature > 32 else ("At freezing" if temperature == 32 else "Below freezing") 'Below freezing' >>> test_temp = lambda temp: "Above freezing" if temp > 32 else ("At freezing" if temp == 32 else "Below freezing") >>> test_temp(32) 'At freezing' >>> >>> >>> >>> test_temp(32) 'At freezing' >>> map(test_temp, [0, 10, 32, 45, 100]) ['Below freezing', 'Below freezing', 'At freezing', 'Above freezing', 'Above freezing'] >>> ================================ RESTART ================================ >>> Positive Positive Positive 0 -> Below freezing 10 -> Below freezing 32 -> At freezing 45 -> Above freezing 100 -> Above freezing >>> ================================ RESTART ================================ >>> >>> >>> factorial(10) Calling decorated factorial with args: (10,), {} Calling decorated factorial with args: (9,), {} Calling decorated factorial with args: (8,), {} Calling decorated factorial with args: (7,), {} Calling decorated factorial with args: (6,), {} Calling decorated factorial with args: (5,), {} Calling decorated factorial with args: (4,), {} Calling decorated factorial with args: (3,), {} Calling decorated factorial with args: (2,), {} Calling decorated factorial with args: (1,), {} Calling decorated factorial with args: (0,), {} 3628800 >>> help(factorial) Help on function inner in module __main__: inner(*args, **kwargs) >>> import inspect >>> inspect.getargspec(factorial) ([], 'args', 'kwargs', None) >>> ================================ RESTART ================================ >>> >>> >>> help(factorial) Help on function factorial in module __main__: factorial(*args, **kwargs) Test simple recursive factorial function (n!) >>> import inspect >>> inspect.getargspec(factorial) ([], 'args', 'kwargs', None) >>> >>> >>> >>> x = 10 >>> if x > 0: print "Positive" else: print "Negative or zero" Positive