Is this a good idea or a waste of time?

Discussion in 'Python' started by asincero, Aug 24, 2006.

  1. asincero

    asincero Guest

    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
     
    asincero, Aug 24, 2006
    #1
    1. Advertising

  2. In <>, asincero
    wrote:

    > 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
     
    Marc 'BlackJack' Rintsch, Aug 24, 2006
    #2
    1. Advertising

  3. asincero

    Guest

    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
     
    , Aug 24, 2006
    #3
  4. asincero

    hiaips Guest

    asincero wrote:
    > 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
     
    hiaips, Aug 25, 2006
    #4
  5. asincero

    Guest

    asincero wrote:
    > 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.
     
    , Aug 25, 2006
    #5
  6. On 24 Aug 2006 20:53:49 -0700, <> wrote:
    > 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)".
     
    Qiangning Hong, Aug 25, 2006
    #6
  7. asincero

    Simon Forman Guest

    asincero wrote:
    > 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
     
    Simon Forman, Aug 25, 2006
    #7
  8. "Simon Forman" <> wrote:

    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
     
    Hendrik van Rooyen, Aug 25, 2006
    #8
  9. On 2006-08-25, Simon Forman <> wrote:
    > asincero wrote:
    >> 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.


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

    --
    Antoon Pardon
     
    Antoon Pardon, Aug 28, 2006
    #9
  10. Antoon Pardon wrote:
    > On 2006-08-25, Simon Forman <> wrote:
    >> ...
    >> 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?
    >

    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
     
    Scott David Daniels, Aug 28, 2006
    #10
  11. On 2006-08-28, Scott David Daniels <> wrote:
    > Antoon Pardon wrote:
    >> On 2006-08-25, Simon Forman <> wrote:
    >>> ...
    >>> 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?
    >>

    > 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.

    --
    Antoon Pardon
     
    Antoon Pardon, Aug 28, 2006
    #11
  12. asincero

    Guest

    Antoon Pardon wrote:
    > 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.
     
    , Aug 28, 2006
    #12
  13. asincero wrote:
    > 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


    --
    Terry Hancock ()
    Anansi Spaceworks http://www.AnansiSpaceworks.com
     
    Terry Hancock, Aug 29, 2006
    #13
  14. On 2006-08-28, <> wrote:
    > Antoon Pardon wrote:
    >> 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.


    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.

    --
    Antoon Pardon
     
    Antoon Pardon, Aug 29, 2006
    #14
  15. At Tuesday 29/8/2006 01:28, Antoon Pardon wrote:

    > > Antoon Pardon wrote:
    > >> 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.

    >
    >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
     
    Gabriel Genellina, Aug 29, 2006
    #15
  16. On 2006-08-29, Gabriel Genellina <> wrote:
    > At Tuesday 29/8/2006 01:28, Antoon Pardon wrote:
    >
    >> > Antoon Pardon wrote:
    >> >> 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.

    >>
    >>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.


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

    --
    Antoon Pardon
     
    Antoon Pardon, Aug 29, 2006
    #16
  17. asincero

    Simon Forman Guest

    Antoon Pardon wrote:
    > On 2006-08-28, <> wrote:
    > > Antoon Pardon wrote:
    > >> 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.

    >
    > 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?

    >
    > --
    > Antoon Pardon
     
    Simon Forman, Aug 29, 2006
    #17
  18. At Tuesday 29/8/2006 02:45, Antoon Pardon wrote:

    > >>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.

    >
    >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
     
    Gabriel Genellina, Aug 29, 2006
    #18
  19. On 2006-08-29, Simon Forman <> wrote:
    > Antoon Pardon wrote:
    >> On 2006-08-28, <> wrote:
    >> > Antoon Pardon wrote:
    >> >> 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.

    >>
    >> 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?


    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.

    --
    Antoon Pardon
     
    Antoon Pardon, Aug 29, 2006
    #19
  20. On 2006-08-29, Gabriel Genellina <> wrote:
    > At Tuesday 29/8/2006 02:45, Antoon Pardon wrote:
    >
    >> >>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.

    >>
    >>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...


    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.

    --
    Antoon Pardon
     
    Antoon Pardon, Aug 29, 2006
    #20
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Sharp

    Generics is a waste of time

    Sharp, May 15, 2005, in forum: Java
    Replies:
    21
    Views:
    877
    Tim Ward
    May 18, 2005
  2. Ben Finney

    How can I waste time ?

    Ben Finney, Feb 19, 2004, in forum: Python
    Replies:
    6
    Views:
    358
    Scott David Daniels
    Feb 20, 2004
  3. Hendrik van Rooyen

    Fw: Is this a good idea or a waste of time?

    Hendrik van Rooyen, Aug 25, 2006, in forum: Python
    Replies:
    2
    Views:
    300
    Hendrik van Rooyen
    Aug 26, 2006
  4. llothar

    Is using splint a waste of time ?

    llothar, Mar 4, 2007, in forum: C Programming
    Replies:
    6
    Views:
    2,037
    Randy Howard
    Mar 11, 2007
  5. Cindy Lee

    .NET MVC = waste of time

    Cindy Lee, Oct 1, 2008, in forum: ASP .Net
    Replies:
    2
    Views:
    639
    Fernando A. Gómez F.
    Nov 21, 2008
Loading...

Share This Page