I'm relatively new to using Python and noticed something strange while Leetcoding the other day. I'm running this with Python 3.8 and get an object attribute error. But the attribute should not be accessed since the condition is true. Seems like this could have been answered already but I could not find a duplicate question. Could anyone help point me in the right direction with this? Thanks for your help.
#AttributeError: 'NoneType' object has no attribute 'val'
a = None
b = (a.val, 0)[a is None]
#works
a=None
if a is None:
b=0
else:
b=a.val
Ok so the reason why the 2nd one works is because a is set to None and it goes to the first if statement and skips the else statement since the first if statement is true. If u were to say like:
a=None
if a is not None:
b=0
else:
b=a.val
This would get an error: AttributeError: 'NoneType' object has no attribute 'val'
.
A Nonetype doesn't have a .val
so I am not sure how you got that from?
a = None
print(a.val)
AttributeError: 'NoneType' object has no attribute 'val'
Either way, if you want to have a ternary operator(btw ternary operator don't exist in python) so a similar way of doing this would be something like:
(I am gonna assume that a.val is a class maybe?)
a = None
b = a.val if a is None else 0
The reason why b = (a.val, 0)[a is None]
gives you an error is cause
if you think about it you are creating a tuple... So python first creates a tuple then does the [a is None]
part. a.val
is undefined so it will give you an error. If you try to do b = (a.val,0)
(notice I remove the index part) it will give you the same error since first it creates a tuple.
b = (a.val,0)[a is None)
is equalivent to:
b = (a.val,0)
b[a is None]
We know that a.val is undefined so it automatically gives you an attribute error.. so the index part isn't the error. It's your tuple part.
Hope this makes sense!