Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Python isdigit() and None
#1
Hi,
Python sys.version_info(major=3, minor=7, micro=9, releaselevel='final', serial=0) on Windows 10 (64)
Thonny 3.3.6
I try to use the isdigit() function to test an input, making sure it is a legal value.

if presets.get('last').isdigit() == True :  
        target.set(presets.get('last'))
This works OK if the input is a digit or a string.
Problem is that for None which will show up often if no value was declared and which certainly is not a digit, it return an error:
AttributeError: 'NoneType' object has no attribute 'isdigit'

From Pythons docs:
"The Python None object, denoting lack of value. This object has no methods. It needs to be treated just like any other object with respect to reference counts."

"Python String isdigit() Method
The isdigit() method returns True if all the characters are digits, otherwise False. Exponents, like ², are also considered to be a digit."
Is this a python issue or my poor understanding?
Reply
#2
In Python it is common style "easier to ask for forgiveness than permission" EAFP.

So pythonic way is to try to get value and handle AttributeError exception.

Regarding None - it has no attributes so no len, no characters etc. Is .isdigit() documentation clear regarding this behaviour? Maybe yes, maybe not.

Quote from Christian Heimes (CPython core developer) about bugs, not ambiguity in documentation, but still relevant in my mind:

Quote:On the one hand you have a project with around 7,500 open bugs, 1,500 open PRs, and new 50 new bugs every week. On the other hand there are a couple of dozen volunteers who spend some of their free time on the same project. The amount of open tickets and PRs is constantly increasing.

The solution obvious is: All it takes is a sufficiently large team so the team can handle all incoming tasks and reduce the backlog slowly.
I'm not 'in'-sane. Indeed, I am so far 'out' of sane that you appear a tiny blip on the distant coast of sanity. Bucky Katt, Get Fuzzy

Da Bishop: There's a dead bishop on the landing. I don't know who keeps bringing them in here. ....but society is to blame.
Reply
#3
I don't know what the 'preset' instance is, but when objects have a get() method, this method often has a default argument. You could use this default argument. Example with dictionaries
>>> spam = {}
>>> spam.get('last')
>>> spam.get('last', '')
''
>>> spam.get('last', '').isdigit()
False
>>> spam.get('last').isdigit()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'isdigit'
Reply
#4
In circumstances like this where the value may be None (or an empty string, list, etc.), one option is to use and to make sure there is a value before trying isdigit().

So, instead of:
if presets.get('last').isdigit()
Do this:
if presets.get('last') and presets.get('last').isdigit()
This works because Python first evaluates if presets.get('last'). If there is no value, the condition is False (because False and x is False no matter what x is), so Python doesn't even evaluate beyond the "and".

Also, since the isdigit() method returns True or False, there is no need for the comparison operator:
if x.isdigit():  # accomplishes the same thing as if x.isdigit() == True:
Gribouillis likes this post
Reply
#5
Thaks all for your replies and suggestions.
I am aware of several potential solutions. Being new to Python, I just wanted to be sure I'm not doing something wrong.
I also found similar isseus with Int:
Quote:if target.get().isdigit() == False or target.get() == '' or target.get() == None :
AttributeError: 'int' object has no attribute 'isdigit'

And a comment as for the "==True", yes, I know it is not necessary, but I never save on clarity. A program should be as detailed as possible. After many years programming in several languages (new to Python, though), I know how difficult it can be to try to understand a program I made myself some 20 years back. (by the way, the True was not always the obvious default. In the past the '== True' was a must.
And one more related comment:
In good programming, eception handling must not be used as a logic programming item. The best practice is to avoid any exception handling while writing the code, and add it only after the code has been completed and tested. It is intended for the unknown or system errors, not for bugs correction or logic decissions.
In addition, the exception handling, if active while programming and testing, will hide other importand error messages.
Reply
#6
The == True is just redundant because if value.isdigit() is perfectly clear. The name isdigit is good because it tells you what the possible answers are (that there are only 2 possibilities of course).
Reply
#7
samtal Wrote:In good programming, eception handling must not be used as a logic programming item. The best practice is to avoid any exception handling while writing the code, and add it only after the code has been completed and tested. It is intended for the unknown or system errors, not for bugs correction or logic decissions.
In addition, the exception handling, if active while programming and testing, will hide other importand error messages.
I don't know from which programming bible this comes from but I don't agree with this, especially in Python. Applying such rules leads to a super defensive programming, the opposite of the Python philosophy. It may apply in strongly typed languages perhaps. There are many creative ways to use exceptions.

For almost 30 years, there have been thousands of programming gurus online. Don't believe all that they say.
snippsat likes this post
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  str.isdigit() vs str.isnumeric() Skaperen 4 3,172 Jun-14-2019, 01:54 AM
Last Post: Skaperen

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020