Defining functions/methods with keyword arguments
A keywords argument has a default value in function or method definition.
def func(pos1, pos2, ..., name1=value1, name2=value2, ...):
Here, pos1, pos2, etc are positional arguments and
name1, name2, etc are keyword arguments with default values value1, value2, respectively.
Keyword arguments cannot appear before positional arguments.
If the function is called without passing a keyword argument, that argument gets its default value.
1def greet(name, greeting="Hello", num_of_times=1):2 for i in range(num_of_times):3 print(greeting, name)45# try the following one at a time:6# greet("Dev")7# greet("Dev", greeting="Hi")8# greet("Dev", num_of_times=3)9# greet("Dev", greeting="Hi", num_of_times=3)10# greet("Dev", num_of_times=3, greeting="Hi")
OOP continued
1class Student:2 """ Represents a student. """34 def __init__(self, student_name, id_num):5 self.name = student_name6 self.id_num = id_num78 def display_info(self):9 print("Name of student:", self.name)10 print("Student ID:", self.id_num)111213new_student = Student("Bob", 260000000)14new_student.display_info()15# Name of student: Bob16# Student ID: 260000000
Let’s add a new attribute to store courses and a new method which allows adding a course.
1s1 = Student("Robin", 26005)2s1.add_course("COMP 208")3s1.add_course("POLI 220", pass_fail=True)4s1.add_course("MATH 250")5s1.display_info()
Name of student: Robin Student ID: 26005 Courses: COMP 208, POLI 220 (pass/fail), MATH 250
- Add an attribute courses, initializing it to empty dictionary. This dictionary will store a course name as a key and a boolean value to indicate whether the course is registered as pass/fail.
- Update display_info method to also display a comma-separate list of course names. If there are no courses in the courses dictionary, do not display any line for it.
- Add a method add_course that takes as a course name (str) and a keyword argument pass_fail (default value: False) and adds them to the attribute courses.
Code available in the file student_methods.py.
Displaying objects: __str__ method
When we display student1 we see what class the object belongs to, and the identity of the object.
1s1 = Student("Dev", 26001)2print(s1)
<__main__.Student object at 0x7f8cd66aa890>
Wouldn’t it be nice to display name, id_num and other attributes when we do print(student1)?
__str__ method
-
We can change the string representation of our class objects by implementing a method called __str__ in our class.
1def __str__(self):2 # must return a string -
If we do that, then when we call print(obj) or str(obj) with an instance obj of our class, __str__ method is called automatically and the returned string is used.
Try it!
In the Student class, add a __str__ method that returns a string in the following format:
Name: <name attribute>
Student ID: <id_num attribute>
Courses: <comma-separated courses>
Then, try to use print with an object of Student class.
Code available in the file student_str.py.
Example — List of Student objects
1students = [Student("Dev", 260001),2 Student("Reza", 260005)]34# Create a student object and append it to the list5students.append(Student("Alice", 260011))67print(students[2]) # uses __str__ of Student class8# Name: Alice9# Student ID: 26001110# Courses: None registered.
1# Continued from previous slide:23print(students) # Does not use __str__ of Student class4# [<__main__.Student object at 0x10ad16100>,5# <__main__.Student object at 0x10ad169d0>,6# <__main__.Student object at 0x10ad16a00>]789for s in students:10 print(s) # uses __str__ of Student class
Try questions on Ed Lessons.
More on special methods
https://docs.python.org/3/reference/datamodel.html#special-method-names
“A class can implement certain operations that are invoked by special syntax (such as arithmetic operations or subscripting and slicing) by defining methods with special names.”
See the files point.py and point_tester.py.
zip function
zip(x, y) function creates an iterable of tuples (xi,yi) where xi is element from x and yi is element from y.
1x_values = [0.5, -2, 5, 10]2y_values = [-1.5, 3, -3.5, 20]34points = list(zip(x_values, y_values))5print(points)6# [(0.5, -1.5), (-2, 3), (5, -3.5), (10, 20)]
1x = [1, 2.5, 5]2y = [2, 4, 10.5]34total = 05for i in range(len(x)):6 total += x[i] * y[i]78print(total)
1x = [1, 2.5, 5]2y = [2, 4, 10.5]34total = 05for x, y in zip(x, y):6 total += x * y78print(total)
What happens when one of the argument lists of zip is shorter than the other?
Truth Value Testing
Any object can be tested for truth value, e.g. when used in an if or while condition.
1x = [1, 2, 3]23if x:4 print("do something")5else:6 print("do other thing")
By default, an object is considered true
- unless its class defines either a special __bool__() method that returns False or a __len__() method that returns zero, when called with the object.
Here are most of the built-in objects considered false:
- Constants defined to be false: None and False
- Zeros: 0, 0.0
- empty sequences and collections: "", tuple(), [], {}, set(), range(0)
Incorrect:
1ans = input('Are you sure? ')23if ans == 'y' or 'yes':4 print('Installing...')
Correct:
1ans = input('Are you sure? ')23if ans == 'y' or ans == 'yes':4 print('Installing...')