- Adding Functions to Python Classes
- Common Mistake
- Instance Methods
- Summary
- Python: How to pass a function as an argument?
- What are Functions in Python?
- Functions as first-class objects
- How to pass a function as an argument in Python?
- 1. User-defined function
- 2. Class method
- 3. Lambda function
- 4. Operator function
- 5. Built-in function
- Conclusion
Adding Functions to Python Classes
Classes can be created as simply a collection of functions. The functions can be defined within the class exactly the same way that functions are normally created. In order to call these functions we need to call it from the class. So the example class called Greetings below takes a name and returns a greeting to the person calling the class.
class Greetings: def good_morning(name): print(f'Good morning ') def good_afternoon(name): print(f'Good afternoon ') def good_evening(name): print(f'Good evening ') Greetings.good_afternoon('John') Greetings.good_morning('Peter') Greetings.good_evening('Jane')
Out: Good afternoon John Good morning Peter Good evening Jane
Common Mistake
Although the class above behaves as we would expect. Let’s take the exact same class and add an __init__. See this article if you don’t know what the __init__ is.
class Greetings: def __init__(self): pass def good_morning(name): print(f'Good morning ') def good_afternoon(name): print(f'Good afternoon ') def good_evening(name): print(f'Good evening ') g = Greetings()
We have created an instance of the Greetings class named g. If we try to call the functions we defined within the class as follows:
TypeError: good_afternoon() takes 1 positional argument but 2 were given
It may not immediately be clear as to why this is happening. The TypeError returned above indicates that we have passed 2 arguments to the function, when it appears we have only passed one. Let’s try calling it without a name to see what happens:
g.good_afternoon() # out: Good afternoon
What is going on here?
When we create an instance of a class the first argument passed to the function is the instance itself. So the reason we are getting the TypeError is that the way Python is reading the g.good_afternoon(‘John’) function is g.good_afternoon(g, ‘John’) although this may seem confusing, it will become clear in the next section why this happens.
Instance Methods
Taking a new example class called Student, which takes a first name, last name, age and major.
class Student: def __init__(self, first, last, age, major): self.first = first self.last = last self.age = age self.major = major def profile(self): print(f"Student name ") print(f"Student age: ") print(f"Major: ") s = Student('Sally' , 'Harris', 20, 'Biology') s.profile()
Out: Student name Sally Harris Student age: 20 Major: Biology
When creating instance methods we must pass the self keyword, this takes care of the issue of the instance being passed to functions as the first argument. Let’s build on the current class and add enrollment functionality to show the ability of instance methods to interact with attributes.
class Student: def __init__(self, first, last, age, major): self.first = first self.last = last self.age = age self.major = major self.courses = [] def profile(self): print(f"Student name ") print(f"Student age: ") print(f"Major: ") def enrol(self, course): self.courses.append(course) print(f"enrolled in ") def show_courses(self): print(f" is taking the following courses") for course in self.courses: print(course) s = Student('Sally' , 'Harris', 20, 'Biology') s.enrol('Biochemistry I') # enrolled Sally in Biochemistry I s.enrol('Literature') # enrolled Sally in Literature s.enrol('Mathematics') # enrolled Sally in Mathematics s.show_courses() # SallyHarris is taking the following courses # Biochemistry I # Literature # Mathematics
All of the methods above have been bound to the instance (we named this instance s), we can check this by using the dir keyword on the instance to see all the attributes and methods bound to s.
Out: ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'age', 'courses', 'enrol', 'first', 'last', 'major', 'profile', 'show_courses']
We can add a mix of instance bound functions and normal functions as defined at the beginning of the document. Below we add a method that prints the current academic year.
import datetime as dt class Student: def __init__(self, first, last, age, major): self.first = first self.last = last self.age = age self.major = major self.courses = [] def profile(self): print(f"Student name ") print(f"Student age: ") print(f"Major: ") def enrol(self, course): self.courses.append(course) print(f"enrolled in ") def show_courses(self): print(f" is taking the following courses") for course in self.courses: print(course) def academic_year(): now = dt.datetime.now() s = now.year, now.year -1 print(f"Current academic year is < str(s[0]) + '/' + str(s[1]) >")
However, we will still get an error if we try to call this new function from an instance, as we have established that calling methods/ functions from an instance always passes the instance itself in as the first argument. So If we wanted to call this academic year function we can do so as follows:
Student.academic_year() # returns: Current academic year is 2020/2019
A better way to handle this will be the topic of the next article on class & static methods.
Summary
— When calling a function from a class the syntax is ClassName.FunctionName()
— When calling a function bound to an instance of a class, the first argument passed in to the function is the instance itself. These are known as methods
— To access and call a method correctly we should pass self in as the first argument when writing the code for the method.
— These methods allow us to interact with attributes associated with the instance / class.
Python: How to pass a function as an argument?
Hello folks! In this tutorial, we are going to discuss the different ways to pass a function as an argument in Python.
What are Functions in Python?
In Python programming, a function plays a very crucial role. We have a very wide and rich collection of different types of functions in Python. Functions in Python provides modularity feature. It means using functions we can divide a single large block of Python code into smaller blocks where each block has to perform a specific task. We can either use predefined functions or define our own functions. The functions which are defined inside a specific class we call them methods in Python.
Functions as first-class objects
First-class objects are those objects which are treated uniformly throughout the program. It means the first-class objects can be stored in a variable, passed as an argument to a function, or used in control statements. Python supports the concept of first-class objects and treats functions as first-class objects. It is because of this reason, we can pass functions as arguments to other functions in Python.
How to pass a function as an argument in Python?
In Python, we can pass different types of functions as an argument to another function in the following ways. Let’s discuss them one by one.
1. User-defined function
In Python, just like a normal variable, we can pass a user-defined function as an argument to another function. A function that accepts another function as its parameter is called a Higher-order function. Let’s see how we can implement this through Python code.
# Define higher order function def fun(foo): result = foo('Welcome To AskPython!!') return result # Define function-1 def fun1(str): return str.lower() # Define function-2 def fun2(str): return str.upper() # Pass funtion-1 as an argument # to fun() function str1 = fun(fun1) print(str1) # Pass funtion-2 as an argument # to fun() function str2 = fun(fun2) print(str2)
welcome to askpython!! WELCOME TO ASKPYTHON!!
2. Class method
Like user-defined functions, we can also pass class methods as an argument. Let’s define a class in Python with two methods and create an object of this class to call those methods. Let’s see the Python code to implement this.
# Define a Python class class demo_class: # Define method-1 def method1(self): print("Method-1 Running") return "AskPython!!" # Define method-2 def method2(self, foo): print("Method-2 Running") result = foo() return result # Create a demo_class object # using the class constructor obj = demo_class() # Pass method-1 as an argument to method-2 str = obj.method2(obj.method1) print(str)
Method-2 Running Method-1 Running AskPython!!
3. Lambda function
In Python, lambda functions are the function objects returned on evaluation of the lambda expressions. Like user-defined functions and class methods, we can also pass a lambda function as an argument to another function. Let’s see the Python code to implement this.
# Create a Python list ls = [1, 2, 3, 4, 5] print('This is the given list:') print(ls) # Pass lambda function # to map() function to claculate # the square of each list element iter_obj = map((lambda n: n**2), ls) # Construct the list again with # square of the elements of the given list ls = list(iter_obj) print('This is the final list:') print(ls)
This is the given list: [1, 2, 3, 4, 5] This is the final list: [1, 4, 9, 16, 25]
4. Operator function
In Python, we have the operator module which contains predefined functions. These functions allow us to perform mathematical, relational, logical, or bitwise operations on a given list of arguments. Like user-defined and lambda functions we can also pass an operator function as an argument to another function. Here we will be using operator.mul() function from the operator module and pass it to the reduce() function which is defined in the functools module along with a Python list. This will calculate and return the product of the passed list elements. Let’s implement this through Python code.
# Importing Python functools module which contains the reduce() function import functools # Importing Python operator module which contains the mul() function import operator # Defining a Python list ls = [1, 3, 5, 7, 9, 11] print("Given Python list:") print(ls) # Pass the mul() function as an argument # to the reduce() function along with the list ls_product = functools.reduce(operator.mul, ls) # Printing the results print("Product of the given Python list: ", ls_product)
Given Python list: [1, 3, 5, 7, 9, 11] Product of the given Python list: 10395
5. Built-in function
In Python, we have so many standard built-in functions like list(), tuple(), dict(), str(), etc. Like the user-defined functions, we can also pass the built-in function as an argument to another function in Python. Here we will pass the str() function to the map() function along with a Python tuple of strings and numbers. This will return an iterator object which we will to the str.join() function to convert the given tuple to Python string. Let’s write the Python code to implement this.
# Create a Python tuple tup = ('Linux', 'Ubuntu', 20.04) print("Given Python tuple:") print(tup) # Pass the str() function # to the map() function iter_obj = map(str, tup) # Construct the string from # the returned iterator object # of the given tuple str1 = "-".join(iter_obj) # Print the result print("Generated Python string from tuple:") print(str1)
Given Python tuple: ('Linux', 'Ubuntu', 20.04) Generated Python string from tuple: Linux-Ubuntu-20.0
Conclusion
In this tutorial, we have learned the following things:
- What is are first-class objects?
- How to pass user-defined function as an argument?
- How to pass class methods as an argument?
- How to pass lambda function as an argument?
- How to pass operator function as an argument?
- How to pass built-in function as an argument?
Hope you have understood all the concepts discussed above and ready to learn and explore more about the functions in Python. Stay tuned with us!