def function_name(arg1, arg2, arg3,....., argN): """function doc string""" function statement block
# A simple function def printer(): print("Welcome to pythoneasy") def add(x, y): """function with parameters """ # This is the doc string print(x + y) def printer(): """function with no parameters """ print("Welcome to pythoneasy") def add(x, y): """function with parameters and return statement""" return x + y # described in the next section # can also be defined in one line def printer():print("Welcome to pythoneasy")
The def keyword will not call the function, that means it will not run the statements inside the function block automatically.
After defining a function we can call it using its name as follows, then the function block will be executed.
function_name() # No arguments function_name(arg1, arg2, arg3,....., argN) # with arguments
The function arguments are passed to the function inside parentheses. (arguments are dependent on function definition)
More about the argument passing will be discussed in the upcoming sections
def printer(): print("Welcome to pythoneasy") printer() # Function is called here and it prints "Welcome to pythoneasy"
We can store the value that returned from the function while calling it like below
value = printer()
More on function return statements can be found in next section.
The return statement in a python function can be written anywhere in the function block or function body.
When it is reached it ends the function call and sends a result back to the caller.
We can return any type of data from the function like string , list or tuple
def foo(): return 10 ret = foo() print(ret) # prints 10
ret stores the value returned from the function
10 is a return value that foo function returns. The return value is optional too. If you do not mention it will return a None value to caller.
def foo(): return ret = foo() print(ret) # prints None
The return statement in python is optional too.
The function without a return statement returns a None value.
def foo(): y = 10 ret = foo() print(ret) # prints None
You can return multiple values from a python function with comma separated values.
The multiple values (comma separated) are always returned as a tuple data type
def foo(): return 10, 20 ret = foo() print(ret) # prints (10, 20) print(type(ret)) # prints <class 'tuple'>
Function arguments are passed to to the function within parentheses while calling a function
def add(a, b): return a + b ret = add(25, 35) print(ret) # prints 60
Function arguments are passed with assignments, so in this case 25 is assigned to a and 35 is assigned to b ..
Then a is getting added to b in this expression a + b , becomes 60 and we have written a return as return a + b , it will return the value 60 to function call.
So 60 gets stored in ret and prints it in the next statement
Functions are type less means you can pass any type of data to the function.
Let us call the same function passing string values to it.
More Examples :
def add(a, b): return a + b p = "Welcome to " e = "PythonEasy" ret = add(p, e) print(ret)
Here p is assigned to a and e is assigned to b. The scope of the a and b is local to the function block and disappears after the function block is exited.
ret = add("Welcome to", "PythonEasy") print(ret) # Welcome to PythonEasy
Here you can see function add has concatenated the two strings using "+" (in this statement
a + b) operator, where in case of integers 25 and 35 it acts as a add function.
So the python function accepts any type of arguments passed to it, but the execution depends how you use the arguments values inside the functions block.
This also called as polymorphism as the same function has multiple behavior
Every argument passed to the python function passed as the reference of the variable to the function.
But passing mutable type of arguments behaves as call by value and immutable type as call by reference . This is not due to property of the function, but due to characteristics of mutable or immutable type.
Let us see these examples
def changing_value(a, b): a = 45 b = "Happy" p = 10 e = ["John", "Doe"] changing_value(p, e) print(p) print(e)
As you can not change the immutable type anywhere, so it behaves like copying the variable to a new one (call by value)
Here p is a mutable type object (integer) , when passed to function it gets assigned to a.
Assigning 45 to a creates a completely new object in the memory(as any immutable type does in the same way for general assignment as follows)
x = 10 y = x y = 15 print(x) # prints x value as 10 as it never changes
In case e (a mutable type - list ), it gets assigned to b inside function. So any change to it ( in this code
b = "Happy") affects the value at outer scope variable e.
This behavior is same as follows.
x = [10, 20, 30] y = x y = 50 print(x) # print [10, 50, 30] The value of x has changed as its mutable type
This not due to p is passed by value and e by reference but the mutable type and immutable data types behave in the same way inside function and in general.