Functions in python

38
Functions in Python arguments, lambdas, decorators, generators

Transcript of Functions in python

Page 1: Functions in python

Functions in Python

arguments, lambdas, decorators, generators

Page 2: Functions in python

Defining simple functions:

>>> def my_func():... print "Inside my function"... >>> my_func()Inside my function

Page 3: Functions in python

Function with arguments - basics

>>> def func_with_args(a, b):... print 'a: ', a... print 'b: ', b... >>> func_with_args(5, 'c')a: 5b: c

Page 4: Functions in python

Two types of arguments

● positional - arguments order matters>>> func_with_args(5, 'c')a: 5b: c

● keyword - argument name mattersfunc_with_args(b=5, a='c')a: cb: 5

Page 5: Functions in python

Mixing position and keyword arguments

>>> def func_with_args(a, b, c):... print a, b, c...

>>> func_with_args(1, c=3, b=2)1 2 3

>>> func_with_args(a=1, 3, b=2) File "<stdin>", line 1SyntaxError: non-keyword arg after keyword arg

Page 6: Functions in python

Passing attributes - old style>>> func_with_args(1, 2, 3) # standart call1 2 3

>>> apply(func_with_args, [1, 2, 3]) # positional1 2 3

>>> apply(func_with_args, [], {'a': 1, 'c': 3, 'b': 2}) # keywords1 2 3

>>> apply(func_with_args, [1], {'c': 3, 'b': 2}) # mixed1 2 3

Page 7: Functions in python

Passing attributes - new style

>>> func_with_args(*[1, 2, 3]) # positional1 2 3

>>> func_with_args(**{'b': 2, 'a': '1', 'c': 3}) # keywords1 2 3

>>> func_with_args(*[1], **{'b': 2, 'c': 3}) # mixed1 2 3

>>> func_with_args(*[1], **{'b': 2, 'a': '1', 'c': 3})TypeError: func_with_args() got multiple values for keyword argument 'a'

Page 8: Functions in python

Function arguments revisited>>> def f(*args, **kwargs):... print args... print kwargs

>>> f()(){}>>> f(1,2,3)(1, 2, 3){}>>> f(a=1, c=3, b=2)(){'a': 1, 'c': 3, 'b': 2}>>> f(1, b=2, c=3)(1,){'c': 3, 'b': 2}

Page 9: Functions in python

Default arguments

>>> def func(a=5):... print a

>>> func()5

>>> func(6)6

>>> func()5

Page 10: Functions in python

Default arguments - part II

>>> def func(a=[]):... print a

>>> func()[]

>>> func(['a'])['a']

>>> func()[]

Page 11: Functions in python

Default arguments - part III

>>> def func(a=[]):... a = a * 5... print a>>> func()[]>>> func()[]>>> func([1])[1, 1, 1, 1, 1]>>> func()[]

Page 12: Functions in python

Default arguments - part IV - problem>>> def func(a=[]):... a.append(2)... print a

>>> func()[2]>>> func()[2, 2]>>> func([1])[1, 2]>>> func()[2, 2, 2]

Page 13: Functions in python

Default arguments - part V - solution

>>> def func(a=None):... a = a or []... a.append(2)... print a...

>>> func()[2]

>>> func()[2]

Page 14: Functions in python

Preloading arguments

>>> def func(a, b, c):... print a, b, c

>>> import functools>>> func_preloader = functools.partial(func, a=5, c=3)>>> func_preloader()TypeError: func() takes exactly 3 arguments (2 given)

>>> func_preloader(b=2)5 2 3

Page 15: Functions in python

Preloading arguments - mixing>>> def func(a, b, c):... print a, b, c

>>> import functools>>> func_preloader = functools.partial(func, a=5, c=3)

>>> func_preloader(2)TypeError: func() got multiple values for keyword argument 'a'

Page 16: Functions in python

Python introspection

""" In computing, type introspection is the ability of a program to examine the type or properties of an object at runtime. """

Wikipedia - Type Introspection

Page 17: Functions in python

Introspection basics

>>> def func(a, b, c):... """ Just an example how introspection works """... pass

>>> help(func)Help on function func in module __main__:func(a, b, c) Just an example how introspection works

Page 18: Functions in python

Methods related to introspection

● type(var) # show the type of the object

● dir(var) # lists object's methods and attributes

● id(var) # return object specific identificator

● getattr(obj, <attribute name>, <default value>)

● hasattr(obj, <attribute name>)

● globals()

● locals()

● callable(obj) # returns True if the object is callable

Page 19: Functions in python

Lambda functions

>>> f = lambda x,y: x+y>>> f(1,2)3

>>> f = lambda x,y=[]: x+y>>> f([1])[1]

>>> f([1], [2])[1, 2]

Page 20: Functions in python

Lambdas and print

# Python 2.7.3>>> a = lambda x: print x # print is a statement File "<stdin>", line 1 a = lambda x: print x

Lambdas can not contain statements

# Python 3.2.3>>> f = lambda x: print(x) # print is a function>>> f(5)5

Page 21: Functions in python

Lambdas usage

>>> map(lambda x: x**2, range(5))[0, 1, 4, 9, 16]

>>> [x**2 for x in range(5)][0, 1, 4, 9, 16]

>>> reduce(lambda a, x: a+x, range(5))10

Avoid using lambdas and check Guido van Rossum's vision for lambdas http://www.artima.com/weblogs/viewpost.jsp?thread=98196

Page 22: Functions in python

Generators

yield x # Generator function send protocol>>> def a():... yield 5... yield 6... yield 7

>>> a()<generator object a at 0x158caa0>

>>> a()<generator object a at 0x158caa0>

Page 23: Functions in python

Generators - range vs xrange

>>> range(10**10)Traceback (most recent call last): File "<stdin>", line 1, in <module>MemoryError

>>> xrange(10**10)xrange(10000000000)

# range has been replaced by xrange in Python 3.x

Page 24: Functions in python

Creating generators>>> def fib():... a, b = 0, 1... while True:... yield a, b... a, b = b, a+b... >>> g = fib()>>> g<generator object fib at 0x19b4be0>

Page 25: Functions in python

Creating generators

>>> g.next()(0, 1)>>> g.next()(1, 1)>>> g.next()(1, 2)>>> g.next()(2, 3)

Page 26: Functions in python

Exhausting generators

>>> def cubes(n):... for i in range(n):... yield i**3>>> c = cubes(3)>>> c.next() # 0>>> c.next() # 1>>> c.next() # 8>>> c.next()Traceback (most recent call last): File "<stdin>", line 1, in <module>StopIteration

Page 27: Functions in python

Generators and comprehension lists

>>> def cubes(n):... for i in range(n):... yield i**3... >>> [a for a in cubes(3)][0, 1, 8]

Page 28: Functions in python

Generators and the send method

>>> def waiting_for_input():... i = 0... while True:... i = yield i**3... >>> f = waiting_for_input()>>> f.next() # 0>>> f.send(8) # 512>>> f.send(10) # 1000>>> f.send(12) # 1728

Page 29: Functions in python

Decorators>>> def decorator(func):... print 'Entering decorator'... return func... >>> @decorator... def f():... print 'Executing F'... Entering decorator>>> f()Executing F

Page 30: Functions in python

Decorators simplified

>>> def decorator(func):... print 'Entering decorator'... return func... >>> @decorator... def f():... print 'Executing F'

# Using the decorator above is the same as using:>>> f = decorator(f)

Page 31: Functions in python

>>> def decorator(func):... def wrap():... print 'Calling function %s' % func.__name__... func()... print 'Exiting decorator'... return wrap... >>> @decorator... def f():... print 'Executing F'... >>> f()Calling function fExecuting FExiting decorator

Functions as Decorators

Page 32: Functions in python

Functions as decorators - part II

>>> def decorator(func):... def wrap(a, b, c):... print 'Function f called with %s, %s, %s' % (a, b, c)... return func(a, b, c)... return wrap ... >>> @decorator... def f(a, b, c):... return a + b + c... >>> f(1, 2, 3)Function f called with 1, 2, 36

Page 33: Functions in python

>>> class decorator(object):... def __init__(self, func):... print 'Initializing decorator'... self.func = func... def __call__(self, *args, **kwargs):... print 'Calling method'... return self.func(*args, **kwargs)>>> @decorator... def f(a, b, c):... return a + b + c... Initializing decorator>>> f(1, 2, 3)Calling method6

Classes as decorators

Page 34: Functions in python

Decorators with arguments

>>> def decorator(debug=False):... def wrap(func):... def f_wrap(a, b, c):... if debug:... print 'Function f called with %s, %s, %s' % (a, b, c)... return func(a, b, c)... return f_wrap... return wrap

Page 35: Functions in python

Decorators with arguments>>> @decorator(debug=True)... def f(a, b, c):... return a + b + c... >>> f(1, 2, 3)Function f called with 1, 2, 36

>>> @decorator(debug=False)... def f(a, b, c):... return a + b + c... >>> f(1, 2, 3)6

Page 36: Functions in python

Q & A

Page 37: Functions in python

Problems to solve

1) Create a function that accept both positional and keyword arguments and returns their sum

2) Create a generator that implements a dice that "brokes" after the 10th roll

3) Create a decorator that converts letters to number according to their position in the alphabet and combine it with the solution of problem #1. When converting letters to numbers make them lowercase and count from 0 i.e. a==0, b==1.

Page 38: Functions in python

About Me

eng. Ilian Iliev

● Web Developer for 9+ years● Python/Django fan for 3+ years● [email protected]● http://ilian.i-n-i.org● https://github.com/IlianIliev/