scalar vs array and program control
lac at openend.se
Sat Jul 25 13:01:21 CEST 2015
You have a bit of a problem, in that "functional" and "object-oriented"
are two different styles of programming. You really cannot make your
code 'more functional' and 'more object-oriented' at the same time --
more in one style implies less in the other. I think you may have
got the mistaken idea that 'object-orientated' means 'well-written'
or 'professional' or some such.
However, if your intuition was telling you that it would be bad to
write code that goes:
if type(x) is str:
elif type(x) is float:
elif type(x) is int:
then your intuition is working perfectly. Don't stick typechecks in all
over your code. It makes it fragile and hard to maintain. It also means
that you have to anticipate all the perfectly good input you might have,
and nobody can do that.
For instance, might somebody want to feed your functions complex numbers
one day? Or, here is a good one -- python has a Decimal datatype
which does Decimal floating point arithmetic. You don't want your code
to not work for people using Decimal numbers just because you didn't
put in a check for
If you find you need to check the type of something, it is better to use
the isinstance function.
if isinstance(x, str):
The python builtin types are all included here. For the sort of work
you do it is useful to know about
from numbers import Number
which will happily return True for all sorts of numbers, complex,
Decimal numbers even number classes which you define yourself.
So if you need to do this sort of 'look before you leap' checking,
isinstance is the way to do it. And sometimes this _is_ the sort of
checking you want to do. But, aside from when you are writing test
code, where it happens all over the place, most of the type in writing
Python code we don't do this either.
We don't look before we leap. We leap, and then if there are any
problems, we deal with it.
Instead we do something like this:
consider a function that converts a string to a number
If all your input is guaranteed to be ints or floats this will work fine.
It also works if you feed it things that are already ints and floats
(not strings). And this is nice .
How did I know to look for ValueErrors?
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: '1.2'
Cause that is what Python gives you. If it had given you a TypeError
instead -- which is what I expected it to do, but so it goes -- I
would have said except TypeError.
You can stack these things.
So now it handles complex numbers as well.
So this is, quite likely, the pattern that you are looking for:
This is the usual way to do things.
If you find that your try/except pairs are walking themselves all the
way to the right hand side of the screen it is time to consider
restructuring your code.
The great advantage of this approach is that you don't have to
pretend to omniscience about the sort of input you will get. If I
decide to call your code with an array of Decimal floating point
integers instead of regular floats, it's great if it just works,
whether or not you had the idea of Decimal floating point in mind
when you wrote the code.
Sorry to be so longwinded. I need to go now and don't have time to
revise it, though it probably should be made a whole bunch less
Hope it helps,
More information about the Python-list