Is this a good idea or a waste of time?

A

asincero

Would it be considered good form to begin every method or function with
a bunch of asserts checking to see if the parameters are of the correct
type (in addition to seeing if they meet other kinds of precondition
constraints)? Like:

def foo(a, b, c, d):
assert type(a) == str
assert type(b) == str
assert type(c) == int
assert type(d) == bool
# rest of function follows

This is something I miss from working with more stricter languages like
C++, where the compiler will tell you if a parameter is the wrong type.
If anything, I think it goes a long way towards the code being more
self documenting. Or is this a waste of time and not really "the
Python way"?

-- Arcadio
 
M

Marc 'BlackJack' Rintsch

asincero said:
def foo(a, b, c, d):
assert type(a) == str
assert type(b) == str
assert type(c) == int
assert type(d) == bool
# rest of function follows

This is something I miss from working with more stricter languages like
C++, where the compiler will tell you if a parameter is the wrong type.
If anything, I think it goes a long way towards the code being more
self documenting. Or is this a waste of time and not really "the
Python way"?

Not really the Python way I'd say. What if `c` is of type `long` for
instance? Your code would stop with an assertion error for a value that
should work. Strict type checking prevents "duck typing" which is a quite
fundamental concept in Python.

Ciao,
Marc 'BlackJack' Rintsch
 
S

skip

Arcadio> Would it be considered good form to begin every method or
Arcadio> function with a bunch of asserts checking to see if the
Arcadio> parameters are of the correct type (in addition to seeing if
Arcadio> they meet other kinds of precondition constraints)?

If it works for you. It's not generally considered Pythonic though. You
should probably read up on "duck typing". Some food for thought: Do you
normally care that the object passed to foo() is a real honest-to-goodness
file object, or do you just care that it has a write() method? You will
learn soon enough if it doesn't, and not that much later than if you have an
assert at the beginning of your function. Of course, sometimes you do truly
care about the type of an object. Then you test. When you care.

Arcadio> This is something I miss from working with more stricter
Arcadio> languages like C++, where the compiler will tell you if a
Arcadio> parameter is the wrong type.

It's a mistake to think that Python's typing is somehow less strict than
C++'s. It's not like Perl where 1 + "2" is valid. It's simply that its
type checks are performed at run-time, not at compile-time. If you're
desparate to have some assistance with your code before you run it, check
out pylint and pychecker.

Skip
 
H

hiaips

asincero said:
Would it be considered good form to begin every method or function with
a bunch of asserts checking to see if the parameters are of the correct
type (in addition to seeing if they meet other kinds of precondition
constraints)? Like:

def foo(a, b, c, d):
assert type(a) == str
assert type(b) == str
assert type(c) == int
assert type(d) == bool
# rest of function follows

This is something I miss from working with more stricter languages like
C++, where the compiler will tell you if a parameter is the wrong type.
If anything, I think it goes a long way towards the code being more
self documenting. Or is this a waste of time and not really "the
Python way"?

-- Arcadio

Many developers who move from a statically-typed languages to dynamic
ones go through this same sort of thought process. I was no different
in that regard, but as I've done more and more Python, I've found that
I just don't encounter type issues all that often. Above all, I see
duck typing as a net benefit - its inherent flexibility far outweighs
the lack of "compile-time" type safety, in my mind.

Along these lines, I'll point you to this article by Bruce Eckel called
"Strong Typing vs. Strong Testing":
http://www.mindview.net/WebLog/log-0025. The bottom line: Focus on unit
tests rather than explicit type checks when you want to verify the
runtime safety of your code. You'll find many more errors this way.

Hope this helps...
--dave
 
S

sjdevnull

asincero said:
Would it be considered good form to begin every method or function with
a bunch of asserts checking to see if the parameters are of the correct
type (in addition to seeing if they meet other kinds of precondition
constraints)? Like:

def foo(a, b, c, d):
assert type(a) == str
assert type(b) == str
assert type(c) == int
assert type(d) == bool
# rest of function follows

That's bad form. If you insist on doing something like this, at least
use "isinstance(a, str)" instead of typeof. But even that breaks duck
typing; if a is a unicode string, that'll fail when the function may
work fine for unicode strings.

You could, of course, test explicitly for the interface you need (e.g.
if you need a to have "lower" and "rjust" methods, do assertion tests
for them). But in practice you're generally better off simply using
the object and getting the exception a few lines lower.

Much of the power of dynamic typing comes from the duck typing concept,
so you should really try to familiarize yourself with it.
This is something I miss from working with more stricter languages like
C++, where the compiler will tell you if a parameter is the wrong type.

Stricter is the wrong word. Python is strictly typed. The difference
here is dynamic vs. static typing.
If anything, I think it goes a long way towards the code being more
self documenting. Or is this a waste of time and not really "the
Python way"?

There are 3 main things that you can do to help here:
1. Choose better names for the arguments so that it's obvious what they
are. I don't advocate Hungarian naming, normally something like "url"
or "shoeSize" will be strongly indicative of what kinds of values are
acceptable.
2. Write docstrings. That will not only document the types but also
how they're used, what gets returned, and perhaps limits on exactly
what ranges of values are acceptable.
3. Write unit tests. They'll catch far more errors than static typing
ever will.
 
Q

Qiangning Hong

That's bad form. If you insist on doing something like this, at least
use "isinstance(a, str)" instead of typeof. But even that breaks duck
typing; if a is a unicode string, that'll fail when the function may
work fine for unicode strings.

To check both str and unicode, you could use "isinstance(a, basestring)".
 
S

Simon Forman

asincero said:
Would it be considered good form to begin every method or function with
a bunch of asserts checking to see if the parameters are of the correct
type (in addition to seeing if they meet other kinds of precondition
constraints)? Like:

def foo(a, b, c, d):
assert type(a) == str
assert type(b) == str
assert type(c) == int
assert type(d) == bool
# rest of function follows

This is something I miss from working with more stricter languages like
C++, where the compiler will tell you if a parameter is the wrong type.
If anything, I think it goes a long way towards the code being more
self documenting. Or is this a waste of time and not really "the
Python way"?

-- Arcadio

Generally asserts should be used to "enforce" invariants of your code
(as opposed to typechecking), or to check certain things while
debugging.

FWIW, if I saw code that that you presented here I'd assume the
programmer who wrote it was either very new(-bie-ish) or just very very
paranoid, so I guess I could say it's not pythonic... :)

BTW, speaking of "strictness", "more stricter" is invalid English,
just "stricter" is the "correct" form. ;-)

Peace,
~Simon
 
H

Hendrik van Rooyen

8<-------------------------------------------------------------

| BTW, speaking of "strictness", "more stricter" is invalid English,
| just "stricter" is the "correct" form. ;-)

or alternatively the construct "more strict" is also acceptable - Hendrik
 
A

Antoon Pardon

Generally asserts should be used to "enforce" invariants of your code
(as opposed to typechecking), or to check certain things while
debugging.

I don't understand this argument. Can't type checking be seen as
enforcing a code invariant?
 
S

Scott David Daniels

Antoon said:
I don't understand this argument. Can't type checking be seen as
enforcing a code invariant?
But it is practically never the "right" invariant. You don't usually
mean type(x) == int, but rather something like x is a prime between 2
and 923. Or 5< x**4 < 429, or _something_ problem specific. saying
that x must be an int is almost always simultaneously too specific and
too general.

--Scott David Daniels
(e-mail address removed)
 
A

Antoon Pardon

But it is practically never the "right" invariant.

And who decides what is and what is not the "right" invariant?
You don't usually
mean type(x) == int, but rather something like x is a prime between 2
and 923. Or 5< x**4 < 429, or _something_ problem specific. saying
that x must be an int is almost always simultaneously too specific and
too general.

There seem to be enough problems that work with ints but not with
floats. In such a case enforcing that the number you work with
is indeed an int seems fully appropiate.
 
S

sjdevnull

Antoon said:
There seem to be enough problems that work with ints but not with
floats. In such a case enforcing that the number you work with
is indeed an int seems fully appropiate.

I've _never_ seen a case where enforcing types in the manner of the OP
is appropriate.

It fails with trivial wrappers like

class myInt(int):
def printFormatted(self):
..........

Even looser checking with isinstance is rarely right. You may want to
exclude floats, but that doesn't mean you want to exclude int-like
objects that don't inherit from int.
 
T

Terry Hancock

asincero said:
Would it be considered good form to begin every method or function
with a bunch of asserts checking to see if the parameters are of the
correct type [...]

This is something I miss from working with more stricter languages
like C++, where the compiler will tell you if a parameter is the
wrong type. If anything, I think it goes a long way towards the code
being more self documenting. Or is this a waste of time and not
really "the Python way"?

Definitely "unpythonic".

It's generally better to ask if an object "acts right" rather than if
it "is right". In other words, if you're going to add two objects,
it's more important that they support addition than that they
are integers, longs, floats, or matrices. This makes your code
more portable, because people might create new numeric types
(say "measurements" or "rationals"). If you leave things open,
then the author of such modules can use your code (they may
have to test special cases if their objects don't behave the same
way as you expect them to, but that becomes their problem).
On the other hand, if your code just arbitrarily breaks because
the objects fail a typecheck, that's an unnecessary obstacle.

If you need assertions, it's better to ask more specifically what will
break the code (e.g. objects that don't support addition -- which
you can check by doing an addition or by looking for th __add__
method. But then, if you need addition support, then your code
probably already has an addition, so why not just let it fail there?).

So be more minimal and throw in checks for specific problems --
especially the ones that would cause a wrong result rather than
an exception.

Cheers,
Terry
 
A

Antoon Pardon

I've _never_ seen a case where enforcing types in the manner of the OP
is appropriate.

It fails with trivial wrappers like

class myInt(int):
def printFormatted(self):
..........

Even looser checking with isinstance is rarely right. You may want to
exclude floats, but that doesn't mean you want to exclude int-like
objects that don't inherit from int.

That may be true. But one may wonder if this is a failing of the
programmer or a failing of the language that doesn't support
such things.
 
G

Gabriel Genellina

That may be true. But one may wonder if this is a failing of the
programmer or a failing of the language that doesn't support
such things.

In any case, I don't see how this supports the original claim that
strict type checking input params is good practice.



Gabriel Genellina
Softlab SRL





__________________________________________________
Preguntá. Respondé. Descubrí.
Todo lo que querías saber, y lo que ni imaginabas,
está en Yahoo! Respuestas (Beta).
¡Probalo ya!
http://www.yahoo.com.ar/respuestas
 
A

Antoon Pardon

In any case, I don't see how this supports the original claim that
strict type checking input params is good practice.

I'm not defending that claim. I'm just putting question marks
with the claim that strict type checking input parameters is
bad practice.
 
S

Simon Forman

Antoon said:
That may be true. But one may wonder if this is a failing of the
programmer or a failing of the language that doesn't support
such things.

What the hell are you talking about?

I'm curious: what is the meaning, to you, of the word "this" in your
sentence above?
 
G

Gabriel Genellina

I'm not defending that claim. I'm just putting question marks
with the claim that strict type checking input parameters is
bad practice.

I think others have shown enough examples of good things that can be
done by *not* enforcing a specific type...



Gabriel Genellina
Softlab SRL





__________________________________________________
Preguntá. Respondé. Descubrí.
Todo lo que querías saber, y lo que ni imaginabas,
está en Yahoo! Respuestas (Beta).
¡Probalo ya!
http://www.yahoo.com.ar/respuestas
 
A

Antoon Pardon

What the hell are you talking about?

Yes, I should have been more clearer.
I'm curious: what is the meaning, to you, of the word "this" in your
sentence above?

That something like "type(x) == int" or "isinstance(x, int)" doesn't
allow to check for all int like objects, nor that there is some python
idiom that should allow you to test for such a thing (although it might
be circumvented).

With that second sentence I mean that there could exist a python
convention that prescribed that all int like objects had to be
subtypes of int. In that case code that followed the convention
could use "isinstance(x, int)" to check for int like objects.
 
A

Antoon Pardon

I think others have shown enough examples of good things that can be
done by *not* enforcing a specific type...

That doesn't contradict that in other situations good things can be
done by enforcing specific type or at least limiting to a subset
of specific types.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,904
Latest member
HealthyVisionsCBDPrice

Latest Threads

Top