0

When I run the code as below, it returns attribute error.

AttributeError: 'Contact' object has no attribute 'find_info'

How should I fix this??

phonebook = {}
Contact = namedtuple('Contact', ['phone', 'email', 'address'])

def add_contact(phonebook):
    name = input()
    phone = input()
    email = input()
    address = input()
    phonebook[name] = Contact(phone, email, address)
    print('Contact {} with phone {}, email {}, and address {} has been added successfully!' .format(name, phonebook[name].phone, phonebook[name].email, phonebook[name].address))
    num = 0
    for i in phonebook.keys():
        if i in phonebook.keys():
            num += 1
    print('You now have', num, 'contact(s) in your phonebook.')
def consult_contact(phonebook):
    find_name = input('What is the name of the contact?\n')
    find_info = input('What information do you need?\n')
    if find_name not in phonebook:
        print('Contact not found!')
    else:
        print(phonebook[find_name].find_info)

if __name__ == "__main__":
    add_contact(phonebook)
    consult_contact(phonebook)



3
  • print(phonebook[find_name].find_info) - the error message would have included relevant line. If such a line (the only usage of find_info as a property as well) is presumed to be valid, remove all non-related code and provide a minimal example case. If the question is about "How can I access a NamedTuple property from a string?", again, remove all non-related code and focus on the specific issue. Commented May 20, 2020 at 18:08
  • Issue resolved by including import statement. from collections import namedtuple Commented May 20, 2020 at 18:12
  • That seems suspect. Without having such in scope, namedtuple itself would have resulted in an error. Commented May 20, 2020 at 18:14

4 Answers 4

2

Your problem is that you're treating find_info as an attribute in consult_phonebook.

Try this:

def consult_contact(phonebook):
    find_name = input('What is the name of the contact?\n')
    find_info = input('What information do you need?\n')
    if find_name not in phonebook:
        print('Contact not found!')
    else:
        print(getattr(phonebook[find_name], find_info))

When using getattr(phonebook[find_name], find_info) you're essentially fetching the attribute stored in find_info from your contact.

Sign up to request clarification or add additional context in comments.

Comments

1

You can use getattr(phonebook[find_name], find_info). Or perhaps change your Contact object to be a dictionary so you can use find_info as an index directly. You can look into some kind of "AttrDict" if you want both attribute and variable key access: Accessing dict keys like an attribute?

2 Comments

Thank you for answering. I've been studying python for only weeks, what does getattr() do?
getattr() lets you access an attribute of an object when you have its name in a variable. Check out docs.python.org/3/library/functions.html#getattr and also look at sister method setattr. In your case, you have the info in a variable called find_info, and the value should be one of phone, email, or address (otherwise getattr will likely fail). Good luck with Python!
1

You cant use the dot notation to access the tuple's attributes like that. The code ends up looking for a method called 'find_info', which doesn't exist.

You can use :

getattr(phonebook[find_name], find_info)

To get the attribute held by the find_info variable.

Comments

0

In your code the value type of find_info is string.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.