1

I was working on Python Classes and found that one cannot call class method from class object by looping through a list of such objects. Below is a sample code:

def show_student_details(*s_list):
    for s in s_list:
        print("Roll Number: ", s.get_roll_no())
        print("Name: ", s.get_name())
        print("Phone: ", s.get_phone())
        print("Marks: ", s.get_marks())

The code for Student class is:

class Student:

    def __init__(self, roll_no=0, name="", phone="", marks=-1):
        self.__roll_no = roll_no
        self.__name = name
        self.__phone = phone
        self.__marks = marks

    def get_roll_no(self):
        return self.__roll_no

    def get_name(self):
        return self.__name

    def get_phone(self):
        return self.__phone

    def get_marks(self):
        return self.__marks

Running this piece of code by passing some objects of Student class gives the following error:

  File "main.py", line 88, in <module>
    show_student_details(students)
  File "main.py", line 12, in show_student_details
    print("Roll Number: ", s.get_roll_no())
AttributeError: 'list' object has no attribute 'get_roll_no'

The thing I understand is that List is itself a Class and Python interprets this code as if I was calling the get_roll_no() function on List Object.

I googled this problem and found that map() and methodcaller() can be used to call the class methods but they didn't work for me.

I know that this question has been asked multiple times on StackOverflow but I think none of them solved my problem which is 'calling multiple class methods from object by selecting objects one by one from a list of class objects.'

Any help will be appreciated. Thanks in Advance.

Tryph
  • 5,946
  • 28
  • 49
Rohit Rawat
  • 449
  • 1
  • 4
  • 14

1 Answers1

1

Assuming you are passing a list of students to the function such as ([<__main__.Student object at 0x122d85990>, <__main__.Student object at 0x122d85910>],) , you can use :

def show_student_details(*s_list):
for s in s_list[0]:
    print("Roll Number: ", s.get_roll_no())
    print("Name: ", s.get_name())
    print("Phone: ", s.get_phone())
    print("Marks: ", s.get_marks())

Because *s_list converts your input to a list. Alternatively, you should be able to just use

def show_student_details(s_list):
for s in s_list:
    print("Roll Number: ", s.get_roll_no())
    print("Name: ", s.get_name())
    print("Phone: ", s.get_phone())
    print("Marks: ", s.get_marks())
Alireza Tajadod
  • 327
  • 1
  • 8
  • 1
    Thank you @Alireza. Using variable length arguments was causing a problem here. Now I get it. – Rohit Rawat Jan 29 '20 at 16:36
  • an alternative could be to unpack the list at function call: `show_student_details(*s_list)`. It depends on what the OP really wants – Tryph Jan 29 '20 at 16:40
  • @Tryph that doesn't work for me. But the second code in Alireza's answer works well. Thanks. – Rohit Rawat Jan 30 '20 at 08:41