def newFunction():
print("Hello World!")
newFunction()
Hello World!
In programming when a sub-set of code is to be execute in one go, we have an option to give a name to that sub-set and that name is now a function. As an analogy consider the steps in making tea.
Make Tea
- Boil water
- Add tea
- Add sugar
- Add milk
Make Tea with options
- Boil water
- Add tea
- Add sugar
- If black tea skip this step
else Add milk
The above steps need to done everytime we make tea. Also, we can create a new sub-set with some customization — “Make Tea with options”. So, whenever we say “make tea” it is implied that the step mentioned above would be performed and we don’t need to mention the steps again; just make tea is enough. Similarly, in programming we can assign a keyword to a code block such that every time that keyword is called all the code within that block gets executed. Contining with our analogy, we now have two “functions” – “Make Tea” and “Make Tea with options”.
So far we have used various in-built Python functions. Now lets look at how we can define our own functions to do a specific task. To define a function, def
keyword is used followed by a function name and parenthesis. The def
statement ends with a colon and the statement within the function are indented (a syntax similar to for
and if
statements). A function can be initialized with or without arguments. To call a function, specify the function name along with parenthesis. Below is a “Hello world!” function.
def newFunction():
print("Hello World!")
newFunction()
Hello World!
The argument(s) that a function takes goes inside the parenthesis when defining the function. An argument can be positional i.e. it must be specificed in a particular sequence or it can be a keyword argument (these can be specified in any order). An important point to note about functions is that the variables within a function have a local scope i.e. a variable declared within a function cannot be accessed outside the function. So, lets say we have a function that does some calculation and we would like to get the result of that calculation. In such cases we need to return the variable(s) using the return
keyword. When calling the function these returned values are assigned to specified variables. Below is an example of a function with two positional arguments. Notice that when call this function the order of argument is important.
def calcPower(a,b):
= a**b
c return c
= calcPower(3,4)
output_1 print(output_1)
= calPower(4,3)
output_2 print(output_2)
81
64
We can have the same funtion with keyword arguments such that now the arguments can be specified in any order. All keyword arguments need to have a default value. If a value for a keyword argument is not specified while calling the function, the default value of the keyword is used.
def calcPower(number=1,power=1):
= number**power
c return c
= calcPower(power=3,number=4)
output_1 print(output_1)
64
It is important to note here that keyword arguments can be specified without keyword as well when calling a function. In this case the order of arguments passed would be matched to the order of the keywords in the function definition.
2,3) calcPower(
8
A function can have both positional and keyword arguments and in such case the keyword arguments must be specified after positional arguments.
It is also possible to have arbitrary number of positional and keyword arguments. The *args
argument maintains a tuple named args
that stores all the arguments passed when a function is called.
def sumNums(*args):
'''This function would add any set of numbers.
It has been defined using *args.'''
= 0
c for num in args:
= c+num
c return c
print(sumNums(4,5,6))
15
The tripple quoted string in the above function not only acts a comment but is also available as help for this function accessible via help
function.
help(sumNums)
Help on function sumNums in module __main__:
sumNums(*args)
This function would add any set of numbers.
It has been defined using *args.
Quiz: Write a function to calculate (a + b)2.
def squareSum(a,b):
= a**2 + b**2 + 2*a*b
c return c
= 4
num1 = 5
num2 print(f"The square of sum of {num1} and {num2} is {squareSum(num1,num2)}.")
The **kwargs
argument is used to have an arbitrary number of keyword arguments. Note the two asterisks. In this case, a kwargs
dictionary is maintained which as the keyword and its value as key-value pairs of the dictionary.
def func1(**kwargs):
= kwargs.keys()
all_keywords = kwargs.values()
all_values return all_keywords, all_values
= func1(name="Sam", age=20)
k1,v1 print(k1)
print(v1)
dict_keys(['name', 'age'])
dict_values(['Sam', 20])
Function is a python file can be accessed in another python code. E.g., we have a file fileA.py
that has function funcInFileA
. Now to call this function from FileB.py
we need to import this function — from fileA import funcInFileA
.
# fileA.py
def funcInFileA():
print("Inside File A")
#fileB.py
from fileA import funcInFileA
funcInFileA()
Inside File A
Save the above two files in the same folder and then execute fileB.py. If we execute file fileA.py then there would be no output since we are not calling the function funcInFileA
in that file. In case we do call funcInFileA
in fileA.py then this function would be called twice upon calling from fileB.py.
If you would like to have an option to call funcInFileA
from both the files and prevent calling it twice when importing this function then you need to use a special variable called __name__
(note the two underscores at the begining and the end). This variable stores the name of the module being executed. Each python file or a module has a __name__
variable associated with it. When a python file is executed this variable is assigned a value __main__.
print(__name__)
__main__
Here the value is __main__ because we are executing the code directly. When we import a function then value of the __name__
variable is set to the filename in which we have the imported function. So the recommend way to call funcInFileA
would be to first check the value of __name__
followed by conditional calling. At the end of fileA.py we can the following code.
#Add this to fileA.py
if __name__ == "__main__":
funcInFileA()
Now, the function is called when we execute either of the files. Upon executing fileB.py, since the function is imported, the __name__
variable for fileA would not be equal to __main__ and hence would not be called because the if condition there would be false.