AmazingDayToday
AmazingDayToday

Reputation: 4272

How to handle error when object has no attribute

I am very new to Python. This is my first ever code in Python! Code that works:

test = {"name": "John Lennon"};
print (test.get("name", 0).split(" ")[1]);

What happens here is that it prints out Lennon, which is expected.

If the code is:

test = {"age": "John Lennon"};
print (test.get("name", 0).split(" ")[1]);

AttributeError: 'int' object has no attribute 'split' will get printed. I understand that this is because the 0 value can't be split.

Is there a way to elegantly/gracefully handle if the value returned is 0 without using if else clause?

Upvotes: 1

Views: 3041

Answers (10)

CristiFati
CristiFati

Reputation: 41116

  • Since the value corresponding to name is a string, so should be the get's default value. In this case it should be the empty string
  • If you want the last name (which will be last element in the list), use -1 index (as it would work even when split will not be able to split the string - and therefore will return a list containing the string)
>>> test0 = {"name": "John Lennon"}
>>> test1 = {"age": "John Lennon"}
>>>
>>> print(test0.get("name", "").split(" ")[-1])
Lennon
>>> print(test1.get("name", "").split(" ")[-1])

>>>

Upvotes: 0

NULLchimp
NULLchimp

Reputation: 775

In your case test.get will give you the corresponding value to your key. If it cannot find it, it will give you the default value, that you provided as second argument. That is an integer 0 and therefore has no split, which is why you get this error. Just use:

test = {"age": "John Lennon"}
print (test.get("name", " ").split(" ")[1])

I hope that helps!

Upvotes: 0

Code-Apprentice
Code-Apprentice

Reputation: 83527

Is there a way to elegantly/gracefully handle if the value returned is 0 without using if else clause?

The best way to handle this is to provide a default value that allows split(). So this means you can use an empty string instead:

print (test.get("name", "").split(" ")[1]);

However, now you get an error with the indexing. You can solve this error by breaking up the long line of code into smaller pieces and assigning intermediate values to variables:

names = test.get("name", "").split(" ")

Then use an if statement to check if there is a last name:

if len(names) >= 2:

Upvotes: 2

Craig
Craig

Reputation: 55

According to this website, the dictionary.get() method has a keyword argument default, which can be set to None like so:

test.get(name, default=None)

This will return None if the key name does not exist in the dictionary. Separating your code into two lines would handle this gracefully:

test = {"name": "John Lennon"};
data = test.get(name, default=None)

if data == None:
    print( data.split(" ")[1] )
else:
    print( "Key {0} not found in 'data.'".format(name) )

Upvotes: 0

user3064538
user3064538

Reputation:

In this case you shouldn't use get. Check if the dictionary contains the key you want to access

test = {"age": "John Lennon"}
if "name" in test:
    print(test["name"].split(" ")[1])
else:
    do_something_else()

Upvotes: 2

milanbalazs
milanbalazs

Reputation: 5329

There is not "name" key in your {"age": "John Lennon"} dict. When you want to read the "name" member (which does not exist in dict) then "get" method gives 0 as default value. And the type of your default value (0) is integer which does not have split method. You should define the default value as string. Like this:

print(test.get("name", " ").split(" ")[1])

Upvotes: 1

Sh3mm
Sh3mm

Reputation: 58

the try/except:

try:
    test = {"age": "John Lennon"}
    print (test.get("name", 0).split(" ")[1])
except AttributeError:
    # doSomething

Upvotes: 0

Bob McCormick
Bob McCormick

Reputation: 225

I'm not sure what you mean by "elegantly handle". If you put a space in the default arg for get, you don't get an error:

>>> test = {"age": "John Lennon"};
>>> print (test.get("name", " ").split(" ")[1]);

>>> 

Upvotes: 0

N Chauhan
N Chauhan

Reputation: 3515

The method I would use is a try-except

try:
    test.get('name', 0).split(' ')[1]
except AttributeError:
    # do something to handle error

Obviously in this case, don’t use a 0 as the default value. Use a valid string that won’t cause an error.

test.get('name', ' ').split(' ')[1]

The more likely error is an IndexError which will occur when the name given is only 1 word.

You can stack these except clauses like elifs:

try:
    test.get('name', 0).split(' ')[1]
except AttributeError:
    # do something to handle error
except IndexError as e:
    # you can use ‘as e’ to use the exception
    # e.g print(e)
except (ValueError, TypeError):
    # you can catch multiple exceptions in one clause

Upvotes: 1

Jack Hamby
Jack Hamby

Reputation: 228

you could use try/except

test = {"age": "John Lennon"}
try:
   print (test.get("name", 0).split(" ")[1])
except:
   print('failed to get name')

OR you could change the default return of .get()

test = {"age": "John Lennon"}
print (test.get("name", " ").split(" ")[1])

Upvotes: 0

Related Questions