strings and ints consistency - isinstance

Steve D'Aprano steve+python at pearwood.info
Wed Sep 21 21:22:14 EDT 2016


On Thu, 22 Sep 2016 12:26 am, Sayth Renshaw wrote:

> Hi
> 
> Trying to clarify why ints and strings arent treated the same.

Because ints and strings are different? :-)


> You can get a valuerror from trying to cast a non-int to an int as in
> int(3.0) however you cannot do a non string with str(a).

Now, that's incorrect. int(3.0) succeeds, it doesn't raise ValueError.

int([]) will raise TypeError.

int("hello world") will raise ValueError, because int() can convert strings,
but only strings with the right value. If the string has an invalid value,
you get a ValueError.

But str(a) should succeed for any object, any value. It should (in
principle) *always* succeed. (If it fails for some object, that object is
buggy.)


> Which means that you likely should use try and except to test if a user
> enters a non-int with valuerror. However as you can't str () and get a
> valuerror you use conditional logic with strings.

What sort of conditional logic do you think you will use to determine
whether or not str(x) will fail?

 
> Therefore to try and keep with pythons only one obvious way of doing
> things should i prefer conditional logic for all using isinstance?

No. There is no connection between the One Obvious Way principle and this.
The principle of One Obvious Way is a design principle that applies to
Python the language and its standard library. (You can also apply it to
your own libraries, because it is a good principle to use.) But it has no
connection to how you test for invalid arguments.

> That way regardless of input type my code flows the same and more
> explicitly states the intended type. Sayth

That is an over-generalisation.

Nobody should care if, in one part of your application, you test for error
conditions using try...except, and in a completely different part of your
application you use an explicit test using if. They are different parts of
code, and there is nothing wrong with them being different.

One Obvious Way does not mean "Only One Way". It means that there must be an
obvious way to solve the problem, not that all problems must be solved the
same way.

When converting arbitrary objects to ints, the obvious way is to try the
conversion and catch TypeError or ValueError if it fails. (And then what?
What will you do with the exception once you have caught it? How do you
recover from this? If you have no way to recover, you probably shouldn't
bother catching the exception.)

When converting arbitrary objects to strings, the obvious way is to assume
that it will succeed.

When dealing with operations that might fail, there are generally two ways
to handle it:

Look Before You Leap (an explicit test using if)

Easier to Ask Forgiveness than Permission (try...except)

https://docs.python.org/3/glossary.html#term-lbyl

https://docs.python.org/3/glossary.html#term-eafp

Use whichever is appropriate for the situation. There is no need to always
use one or the other.




-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.




More information about the Python-list mailing list