2

I'm learning and experimenting with Python. How can I pass the contact_list in my second function print_contacts so that it can print the name from the contact_list? I'm sure I am doing something wrong, can anyone please explain why is it so?

class Contact(object):
    contact_list = []

    def __init__(self, name, email):
        self.name = name
        self.email = email
        return Contact.contact_list.append(self)

# How to pass contact_list to below function?

    def print_contacts(contact_list):
        for contact in contact_list:
            print(contact.name)
Ma0
  • 15,057
  • 4
  • 35
  • 65
Hannan
  • 1,171
  • 6
  • 20
  • 39
  • print_contacts(Contact.contact_list), comments in python are marked with a `#` not `//`, also you need to mark the second function as a classmethod or either factor it out – arielnmz Jul 19 '17 at 16:09
  • __init__ methods do not return any meaningful value. So basically you should just do `Contact.contact_list.append(self)` because `return` there does nothing useful. And, list.append() does not return anything anyway... – little_birdie Jul 19 '17 at 16:22

2 Answers2

2

To me it doesn't make any sense to have a Contact object also own a contact_list attribute, and even less if it's class-wide instead of instanced. I would do this instead:

class Contact(object):
    def __init__(self, name, email):
        self.name = name
        self.email = email

    def __str__(self):
        return f"{self.name} <{self.email}>"
        # or "{} <{}>".format(self.name, self.email) in older versions of
        # python that don't include formatted strings


contacts = []

def print_contacts(contacts: "list of contacts") -> None:
    for c in contacts:
        print(c)

adam = Contact("Adam Smith", "adam@email.com")
contacts.append(adam)

bob = Contact("Bob Jones", "bob@email.com")
contacts.append(bob)

charlie = Contact("Charlie Doe", "charlie@email.com")
contacts.append(charlie)

print_contacts(contacts)
# Adam Smith <adam@email.com>
# Bob Jones <bob@email.com>
# Charlie Doe <charlie@email.com>

Or alternatively, model an AddressBook that knows how to create Contact objects and display them all.

class AddressBook(list):
    def add_contact(self, *args, **kwargs):
        new_contact = Contact(*args, **kwargs)
        self.append(new_contact)

    def display_contacts(self):
        for contact in self:
            print(contact)

contacts = AddressBook()
contacts.add_contact("Adam Smith", "adam@email.com")
contacts.add_contact("Bob Jones", "bob@email.com")
contacts.add_contact("Charlie Doe", "charlie@email.com")
contacts.display_contacts()
Adam Smith
  • 52,157
  • 12
  • 73
  • 112
1
class Contact(object):
  contact_list = []

  def __init__(self, name, email):
      self.name = name
      self.email = email
      Contact.contact_list.append(self)

  @classmethod
  def print_contacts(cls):
      for contact in cls.contact_list:
          print(contact.name)

cont1 = Contact("John", "john@john.com")
cont2 = Contact("Mary", "mary@mary.com")
Contact.print_contacts()

will print

>>John
  Mary

To answer your question as to why your code currently doesn't work: first, your init method doesn't need a return call, init is called upon object creation to establish object variables and typically doesn't need to return anything (especially in this case since .append() doesn't provide anything to return). Second, a classmethod seems better suited for what you are trying to do with the second method, and you can read more about that here: What are Class methods in Python for?

SeeDerekEngineer
  • 770
  • 2
  • 6
  • 22