Object type check

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • king kikapu

    Object type check

    Hi to all,

    in statically-types languages, let's say C# for example, we use
    polymorphism through interfaces. So we define an interface I with
    method M and then a class C that implements I interface and write code
    for the M method.
    So, if we have a function that takes a parameter of type I, we know
    before-hand that it will have an M method to call.

    But in dynamic languages this is not the case and we can pass whatever
    we want to that function. Assuming that someone writes a library in
    Python that other programmers will use, what is the correct way to
    check inside that function if the parameter passed is of the correct
    type, maybe "isinstance " BIF ?

    Thanks in advance!

  • Calvin Spealman

    #2
    Re: Object type check

    The answer is to do nothing at all. Use the interfaces of the objects
    that you expect. Treat them like numbers if you expect them to be, or
    stirngs, or iterables. Call methods and access attributes you expect
    to be there. If the caller passes sometihng bad, and something doesn't
    work, they'll find out about it and consult your documentation to see
    what they did wrong. Dont restrict them to particular types. You would
    not restrict them to a particular class in C#. Instead, you define the
    interfaces simply by how you use the objects. This is called duck
    typing (http://en.wikipedia.org/wiki/Duck_typing) which states "If it
    walks like a duck and it quacks like a duck, it must be a duck." In
    the end, isn't that what matters to you? Not the type or defined
    interfaces of an object, but that it does what you expect.

    On 7 Feb 2007 08:17:55 -0800, king kikapu <aboudouvas@pan afonet.grwrote:
    Hi to all,
    >
    in statically-types languages, let's say C# for example, we use
    polymorphism through interfaces. So we define an interface I with
    method M and then a class C that implements I interface and write code
    for the M method.
    So, if we have a function that takes a parameter of type I, we know
    before-hand that it will have an M method to call.
    >
    But in dynamic languages this is not the case and we can pass whatever
    we want to that function. Assuming that someone writes a library in
    Python that other programmers will use, what is the correct way to
    check inside that function if the parameter passed is of the correct
    type, maybe "isinstance " BIF ?
    >
    Thanks in advance!
    >
    --

    >

    --
    Read my blog! I depend on your acceptance of my opinion! I am interesting!

    Comment

    • Michele Simionato

      #3
      Re: Object type check

      On Feb 7, 5:17 pm, "king kikapu" <aboudou...@pan afonet.grwrote:
      Hi to all,
      >
      in statically-types languages, let's say C# for example, we use
      polymorphism through interfaces. So we define an interface I with
      method M and then a class C that implements I interface and write code
      for the M method.
      So, if we have a function that takes a parameter of type I, we know
      before-hand that it will have an M method to call.
      >
      But in dynamic languages this is not the case and we can pass whatever
      we want to that function. Assuming that someone writes a library in
      Python that other programmers will use, what is the correct way to
      check inside that function if the parameter passed is of the correct
      type, maybe "isinstance " BIF ?
      Usually, you don't check anything at all. However, in some cases, it
      may make
      sense to check that you passed the right object.
      For instance if you have the container

      class Example(object) :
      def __init__(self, innerobj):
      self.innerobj = innerobj
      def amethod(self):
      self.innerobj.a method()

      ex = Example(None)

      you will get an error only when calling ex.amethod(). If you are going
      to call
      ex.amethod() one hour after instantiation, you will get the error too
      late.
      So, it makes sense to put a check in the __init__ method, something
      like

      assert hasattr(self.in nerobj, 'amethod')

      in order to get an error message as soon as possible. Notice that
      checking for the existance
      of the needed method is better than using isinstance, since it gives
      you much more
      freedom for innerobj. Do not require more than you need.
      HTH,

      Michele Simionato

      Comment

      • king kikapu

        #4
        Re: Object type check

        Dont restrict them to particular types. You would
        not restrict them to a particular class in C#. Instead, you define the
        interfaces simply by how you use the objects.
        Of cource i restrict them to particular types! In C# you cannot pass
        something bad
        this way because the compiler will just catch it!

        I see what you mean by "duck typing". So you suggest the "do nothing
        at all" direction,
        better document my code so other can see what is expected, right ?

        Comment

        • Calvin Spealman

          #5
          Re: Object type check

          On 7 Feb 2007 08:59:12 -0800, king kikapu <aboudouvas@pan afonet.grwrote:
          Dont restrict them to particular types. You would
          not restrict them to a particular class in C#. Instead, you define the
          interfaces simply by how you use the objects.
          >
          Of cource i restrict them to particular types! In C# you cannot pass
          something bad
          this way because the compiler will just catch it!
          No, you restrict the interfaces, in your example, not the classes. It
          is the same in python, but the interfaces are implicitly defined by
          how you use the objects.
          I see what you mean by "duck typing". So you suggest the "do nothing
          at all" direction,
          better document my code so other can see what is expected, right ?
          Yes. Also, remember that this means if you write code to expect a
          dictionary, any mapping type that supports the operations and methods
          you use will work transparently, allowing your code to be much more
          flexible.

          --
          Read my blog! I depend on your acceptance of my opinion! I am interesting!

          Comment

          • Eduardo \EdCrypt\ O. Padoan

            #6
            Re: Object type check

            Of cource i restrict them to particular types! In C# you cannot pass
            something bad
            this way because the compiler will just catch it!
            And you cant pass something 'good' that immitates another object
            interface (a file-like object for example)
            I see what you mean by "duck typing". So you suggest the "do nothing
            at all" direction,
            better document my code so other can see what is expected, right ?
            I would add UnitTests to it.
            --
            EduardoOPadoan (eopadoan->altavix::com )

            Comment

            • Bruno Desthuilliers

              #7
              Re: Object type check

              king kikapu a écrit :
              Hi to all,
              >
              in statically-types languages, let's say C# for example, we use
              polymorphism through interfaces. So we define an interface I with
              method M and then a class C that implements I interface and write code
              for the M method.
              So, if we have a function that takes a parameter of type I, we know
              before-hand that it will have an M method to call.
              >
              But in dynamic languages this is not the case and we can pass whatever
              we want to that function.
              Yes. And this is a Good Thing (tm).
              Assuming that someone writes a library in
              Python that other programmers will use, what is the correct way to
              check inside that function if the parameter passed is of the correct
              type, maybe "isinstance " BIF ?
              The correct way in Python is to *not* check. Just document what kind of
              interface you expect, and it's ok. If the people using your code are stupid
              and lazy enough to not read the doc, then you can't help .

              Comment

              • Bruno Desthuilliers

                #8
                Re: Object type check

                king kikapu a écrit :
                >>Dont restrict them to particular types. You would
                >>not restrict them to a particular class in C#. Instead, you define the
                >>interfaces simply by how you use the objects.
                >
                >
                Of cource i restrict them to particular types! In C# you cannot pass
                something bad
                this way because the compiler will just catch it!
                This won't prevent some stupid to implement the interface with a totally
                different semantic (what about some getter wiping out your hard drive ?).

                FWIW, in Python, you can't pass something bad because it will raise an
                exception. Well, to be true, there's *one* gotcha : passing a string
                where a list or tuple is expected may in some occasions yield strange
                results (strings being sequences too).
                I see what you mean by "duck typing". So you suggest the "do nothing
                at all" direction,
                better document my code so other can see what is expected, right ?
                Exactly.

                Comment

                • king kikapu

                  #9
                  Re: Object type check

                  at first, thanks you all for your help!

                  So, i will follow your advice.In a moment though, i thought that "ok,
                  do not check anything of the parameter's type but do a try/catch at
                  the calls inside the function"

                  But this way, i would rather defeat the purpose because i have to try/
                  catch in *every* call inside the func.
                  So, i suppose that i wouldn't want to do that and just try to make the
                  call in whatever they passed me in.

                  Strange world the dynamic one....

                  Comment

                  • Bruno Desthuilliers

                    #10
                    Re: Object type check

                    king kikapu a écrit :
                    at first, thanks you all for your help!
                    >
                    So, i will follow your advice.In a moment though, i thought that "ok,
                    do not check anything of the parameter's type but do a try/catch at
                    the calls inside the function"
                    And so what ? Once an exception got caught, what are you going to do ?
                    Raise another exception ? Re-raise the same exception ? In both cases, you
                    usually don't gain much - and sometimes loose (time, simplicity,
                    readability, and
                    a usefull traceback).

                    Unless you know how to handle it, it's usually better to let the exception
                    propagate. Usually, the person coding the *application* (ie: the coder using
                    your lib) will wrap the whole thing into a catch-all exception handler
                    at the higher level,
                    so he can log the full traceback, display a nice error to the end user,
                    and crash gracefully.
                    As a library programmer, you should not care about this.
                    But this way, i would rather defeat the purpose because i have to try/
                    catch in *every* call inside the func.
                    So, i suppose that i wouldn't want to do that and just try to make the
                    call in whatever they passed me in.
                    You're starting to see the light, my friend !-)
                    Strange world the dynamic one....
                    If that's too dynamic for you, then run for your life - this is just the
                    visible
                    part of the iceberg.

                    Comment

                    • king kikapu

                      #11
                      Re: Object type check

                      And so what ? Once an exception got caught, what are you going to do ?

                      You have absolutely right, that's the reason i rejected this.
                      You're starting to see the light, my friend !-)
                      >
                      Strange world the dynamic one....
                      >
                      If that's too dynamic for you, then run for your life

                      Hehe...you know, it is a little bit strange if you are used to Delphi,
                      C# or any other statically-typed language and suddenly you starting
                      programming in a dynamic one, really strange! :)
                      All of the efforts all these years to declare everything correct, to
                      fight with the compiler (and to always have him win...), to ...[put
                      whatever here] and now Python...What can i say!...

                      Thanks for the help!

                      Comment

                      • Bruno Desthuilliers

                        #12
                        Re: Object type check

                        king kikapu a écrit :
                        >>And so what ? Once an exception got caught, what are you going to do ?
                        >
                        >
                        You have absolutely right, that's the reason i rejected this.
                        hear hear !-)

                        ( snip)
                        All of the efforts all these years to declare everything correct, to
                        fight with the compiler (and to always have him win...), to ...[put
                        whatever here] and now Python...What can i say!...


                        Comment

                        • Steven D'Aprano

                          #13
                          Re: Object type check

                          On Wed, 07 Feb 2007 08:59:12 -0800, king kikapu wrote:
                          I see what you mean by "duck typing". So you suggest the "do nothing
                          at all" direction,
                          better document my code so other can see what is expected, right ?
                          Generally speaking, yes, but not always.

                          The usual Python model is "better to ask forgiveness than permission". For
                          example, these two snippets of code do (more or less) the same thing, but
                          the second is more in the Pythonic style:


                          # Look Before You Leap
                          if isinstance(x, SomeClass):
                          x.somemethod()
                          else:
                          do_something_el se()

                          # Better To Ask For Forgiveness Than Permission
                          try:
                          x.somemethod()
                          except AttributeError: # no such method exists
                          do_something_el se()


                          Setting up a try...except block is cheap in Python, so it costs very
                          little to try calling the method, then take a different action only if it
                          is one of the rare failures. (However, catching the exception is
                          expensive, so if you have lots of failures, you might want to rethink your
                          strategy.)

                          But sometimes this isn't what you want. Here's a counter example:

                          def modify(list_of_ x):
                          for x in list_of_x:
                          x.change_in_pla ce()

                          Note that there's no "do_something_e lse" to do if an item doesn't have
                          the correct method. That's bad data, and no recovery is possible, so
                          you just let the exception propagate. But there's a problem: if the
                          calling code catches the exception, as it may, you leave the list_of_x
                          in an intermediate state where some of the items have been changed and
                          some haven't.

                          The solution is a form of Look Before You Leap that doesn't break
                          duck-typing:

                          def modify(list_of_ x):
                          for x in list_of_x:
                          try:
                          x.change_in_pla ce # don't call the method, just check it exists
                          # we can check as many or as few methods as we need, e.g.:
                          x.__getitem__ # check that x is indexable
                          except AttributeError:
                          raise ValueError("lis t contains an invalid item")
                          # if we get here, we know it is safe to proceed
                          for x in list_of_x:
                          x.change_in_pla ce()

                          Now each item doesn't have to be an instance of SomeClass, but merely
                          needs to have the right signature.


                          --
                          Steven D'Aprano

                          Comment

                          • king kikapu

                            #14
                            Re: Object type check

                            def modify(list_of_ x):
                            for x in list_of_x:
                            try:
                            x.change_in_pla ce # don't call the method, just check it exists
                            XXmmmm...what exactly is going on here ? I mean, what is actually
                            happens if you omit the parenethesis as you just did ? I understand
                            that it does not call the method, but what is really doing ??

                            Comment

                            • Michele Simionato

                              #15
                              Re: Object type check

                              On Feb 8, 12:00 pm, "king kikapu" <aboudou...@pan afonet.grwrote:
                              def modify(list_of_ x):
                              for x in list_of_x:
                              try:
                              x.change_in_pla ce # don't call the method, just check it exists
                              >
                              XXmmmm...what exactly is going on here ? I mean, what is actually
                              happens if you omit the parenethesis as you just did ? I understand
                              that it does not call the method, but what is really doing ??
                              See http://users.rcn.com/python/download/Descriptor.htm for more than
                              you ever wanted
                              to know about attribute access in Python.

                              Michele Simionato

                              Comment

                              Working...