Functions must be defined (or coded earlier in the script) before they can be called as shown below:
[postgres@postgres-desktop:~]$ python myfunction.py (01-18 00:06)
Traceback (most recent call last):
File "myfunction.py", line 1, in <module>
a = square(10)
NameError: name 'square' is not defined
Below is a listing of myfunction.py
a = square(10)
print a
def square(x):
return x*x
You use the keyword "def" to define a function. Just like in C, the function arguments goes inside the parentheses and are parsed in the same order that they are passed. You then terminate the "def" statement with a colon. You then indent the contents of the function. A function may, or may not return a value, pretty much like in C.
The reason why an exception was thrown when the code was run is that the function was defined after it was called and hence, the interpreter is not yet aware of its existence when the call was made. Remember, the way python works is that it reads the py file in sequence, starting at the beginning, interpreting it, and then executing the interpreted line.
To correct this, place the function definition ahead of its call like this:
def square(x):
return x*x
a = square(10)
print a
When you run it, the result is as expected:
[postgres@postgres-desktop:~]$ python myfunction.py (01-18 00:18)
100
Python knew the end of function definition when the indentation ends. One thing with python is that you could mix the function definition with the the main body and still works fine. In C, you can't do this. However, this could easily make yourself confused. So, avoid it. Below is an example:
# my function.py
y = 10
def square(x):
return x*x
a = square(y)
print a
Below is the result when you run it:
[postgres@postgres-desktop:~]$ python myfunction.py (01-18 00:23)
100
As you could see, it still runs without error.
You could define an empty function definition like this:
def square(x):
pass
which is equivalent to this C function
float square(float x)
{
}
DEFAULT VALUES
It is very easy to set default values in function definition. To illustrate:
>>> def whoAmI(name, age, sex='male'):
... print 'I am ' + name + ', ' + str(age) + ' yrs old, ' + sex
...
>>> whoAmI('John', 33)
I am John, 33 yrs old, male
>>> whoAmI('Ann', 24, 'female')
I am Ann, 24 yrs old, female
In the first function call, only the name and age were passed. Since nothing was supplied for sex (i.e., only 2 arguments were supplied), it used the default value of sex, which is "male".
In the second call, all 3 arguments were supplied and the supplied value for sex was used.
Remember, the order by which the arguments were passed, will be the order they will be assigned on the variables at the receiving function.
Another thing to remember for assigning default values is that they should be at the end and not to be followed by non-default argument as shown below:
>>> def whoAmI(name, sex='male', age):
... print 'I am ' + name + ', ' + str(age) + ' yrs old, ' + sex
...
File "<stdin>", line 1
SyntaxError: non-default argument follows default argument
NAMED ARGUMENTS
Use of named arguments is illustrated below:
>>> def whoAmI(name, age, sex):
... print 'I am ' + name + ', ' + str(age) + ' yrs old, ' + sex
...
>>> whoAmI(age=20, sex='female', name='Mary')
I am Mary, 20 yrs old, female
As you could see, using named argument when you make a function call enables you to pass the arguments in any order you want and still get the desired result. The added advantages are: 1. It makes your code clearer because it reminds you which values goes to which variables when you make the call, and 2. It is easier to handle default values as illustrated below:
>>> def whoAmI(name, sex='male', age=25):
... print 'I am ' + name + ', ' + str(age) + ' yrs old, ' + sex
...
>>> whoAmI('Kim', age=44)
I am Kim, 44 yrs old, male
>>> whoAmI(sex='female', name='Mary')
I am Mary, 25 yrs old, female
VARIABLE NUMBER OF ARGUMENTS
Remember the printf function in C? You pass any number of arguments and it works fine. Here is how you do it in python:
>>> def f(*v):
... for u in v:
... print u
...
>>> f(10, 20, 30)
10
20
30
>>> f(1234)
1234
>>> f('are','you','human',12.5)
are
you
human
12.5
Notice the asterisk (*) before the variable 'v' in the function argument. It is like saying that this variable will be a list to hold all parameters that were passed. You access the function arguments by iterating this 'list' variable.
You could actually combine the positional arguments with variable arguments like this:
>>> def g(positional, *variable):
... print 'positional argument is: ' + str(positional)
... print 'variable arguments are: ' + str(variable)
...
>>> g(10, 20, 30, 40)
positional argument is: 10
variable arguments are: (20, 30, 40)
Here is another example:
>>> def h(a, b, c, *d):
... print 'a=' + str(a)
... print 'b=' + str(b)
... print 'c=' + str(c)
... print 'variable argument d=' + str(d)
...
>>> h(11, 22, 33, 44, 55, 66, 77, 88)
a=11
b=22
c=33
variable argument d=(44, 55, 66, 77, 88)
Positional arguments should come first before variable arguments or there will be an exception.
KEYWORD ARGUMENTS
Here is how you handle a variable number of keyword arguments - you place double asterisk before the variable name on the receiving function and then, the keyword arguments are converted into a dictionary. The variable names that were passed were converted into a string.
>>> def f(**k):
... print k
...
>>> f(a='apple', b='banana')
{'a': 'apple', 'b': 'banana'}
>>> f(x=1, y='yarn',z=2)
{'y': 'yarn', 'x': 1, 'z': 2}
GENERAL FORMAT OF FUNCTION ARGUMENTS
The general format is that you have the positional arguments first, followed by variable arguments, then finally, the variable keyword arguments. Here is an example:
>>> def g(a,b, *args, **kwargs):
... print 'positional arguments are: a=' + str(a) + ', b=' + str(b)
... print 'variable arguments args=' + str(args)
... print 'keyword arguments kwargs=' + str(kwargs)
...
>>> g(10, 20, 30, 40, 50, 60, m='model', c='cat', x=100)
positional arguments are: a=10, b=20
variable arguments args=(30, 40, 50, 60)
keyword arguments kwargs={'x': 100, 'c': 'cat', 'm': 'model'}
FUNCTIONS AS FIRST CLASS OBJECTS IN PYTHON
In python, functions are treated just like strings or integers in the sense that you could pass them around as if they were data. The examples below illustrates the important points:
>>> def add(x,y):
... print 'inside add function'
... return x+y
...
>>> def sub(x,y):
... print 'inside sub function'
... return x-y
...
>>> def multiply(x,y):
... print 'inside multiply function'
... return x*y
...
>>> z = add # you could assign the function to a variable
>>> z(3,4) # and then invoke it through that variable
inside add function
7
>>> def doThis(func,x,y): # invokes the function passed to this function
... print 'inside doThis function, about to call another function'
... return func(x,y)
...
>>> doThis(sub,7,5)
inside doThis function, about to call another function
inside sub function
2
>>> doThis(multiply,4,5)
inside doThis function, about to call another function
inside multiply function
20
You could also create a dictionary of function and invoke it.
>>> switch = {'add':add, 'sub':sub, 'mul':multiply}
>>> switch['add'](4,3)
inside add function
7
>>> x = 'mul'
>>> switch[x](3,5)
inside multiply function
15
So, if you miss C's or VB's 'switch' statement, the above example demonstrates how to elegantly handle it in python.
No comments:
Post a Comment