How to make a function associated with a class?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Kurda Yon

    How to make a function associated with a class?

    Hi,

    I have a class called "vector". And I would like to define a function
    "dot" which would return a dot product of any two "vectors". I want
    to call this function as follow: dot(x,y).

    Well, I can define a functions "dot" outside the class and it works
    exactly as I want. However, the problem is that this function is not
    associated with the class (like methods a method of the class).

    For example, if I call "x.calc()" or "y.calc()", python will execute
    different methods if "x" and "y" belongs to different classes. I want
    to have the same with my "dot" function. I.e. I want it calculates the
    dot product ONLY IF the both arguments of that function belong to the
    "vector" class.

    Is it possible?

    Thank you in advance.
  • bruno.desthuilliers@gmail.com

    #2
    Re: How to make a function associated with a class?

    On 1 juil, 22:43, Kurda Yon <kurda...@yahoo .comwrote:
    Hi,
    >
    I have a class called "vector". And I would like to define a function
    "dot" which would return a dot product of any two "vectors". I want
    to call this function as follow: dot(x,y).
    >
    Well, I can define a functions "dot" outside the class and it works
    exactly as I want. However, the problem is that this function is not
    associated with the class (like methods a method of the class).
    >
    For example, if I call "x.calc()" or "y.calc()", python will execute
    different methods if "x" and "y" belongs to different classes. I want
    to have the same with my "dot" function. I.e. I want it calculates the
    dot product ONLY IF the both arguments of that function belong to the
    "vector" class.
    >
    Is it possible?
    You don't need to make dot() a method of your Vector class to have
    this behaviour, and making it a method of the Vector class isn't
    enough to have this behaviour.

    The simplest solution would be:

    class Vector(object):
    def dot(self, other):
    if not isinstance(othe r, type(self)):
    raise TypeError("can only calculate the dot product of two
    vectors")
    # do the job here and return what's appropriate

    Now since it's a binary operator, you might as well implement it as
    such:

    class Vector(object):
    def __mul__(self, other):
    if not isinstance(othe r, type(self)):
    raise TypeError("can only calculate the dot product of two
    vectors")
    # do the job here and return what's appropriate

    Then use it as doproduct = vector1 * vector2


    HTH

    Comment

    • Kurda Yon

      #3
      Re: How to make a function associated with a class?

      On Jul 1, 5:01 pm, "bruno.desthuil li...@gmail.com "
      <bruno.desthuil li...@gmail.com wrote:
      On 1 juil, 22:43, Kurda Yon <kurda...@yahoo .comwrote:
      >
      >
      >
      Hi,
      >
      I have a class called "vector". And I would like to define a function
      "dot" which would return a dot product of any two "vectors". I want
      to call this function as follow: dot(x,y).
      >
      Well, I can define a functions "dot" outside the class and it works
      exactly as I want. However, the problem is that this function is not
      associated with the class (like methods a method of the class).
      >
      For example, if I call "x.calc()" or "y.calc()", python will execute
      different methods if "x" and "y" belongs to different classes. I want
      to have the same with my "dot" function. I.e. I want it calculates the
      dot product ONLY IF the both arguments of that function belong to the
      "vector" class.
      >
      Is it possible?
      >
      You don't need to make dot() a method of your Vector class to have
      this behaviour, and making it a method of the Vector class isn't
      enough to have this behaviour.
      >
      The simplest solution would be:
      >
      class Vector(object):
      def dot(self, other):
      if not isinstance(othe r, type(self)):
      raise TypeError("can only calculate the dot product of two
      vectors")
      # do the job here and return what's appropriate
      >
      Now since it's a binary operator, you might as well implement it as
      such:
      >
      class Vector(object):
      def __mul__(self, other):
      if not isinstance(othe r, type(self)):
      raise TypeError("can only calculate the dot product of two
      vectors")
      # do the job here and return what's appropriate
      >
      Then use it as doproduct = vector1 * vector2
      >
      HTH
      As far as I understood, In the first case, you gave, I need to call
      the function as follows "x.dot(y)". In the second case I need to call
      the function as follows "x*y". But I want to call the function as
      follows "dot(x,y)".

      By the way, "type(self) " returns the name of the class to which the
      "self" belongs?
      Does "instance" return "true" if the first argument belongs to the
      class whose name is given in the second argument?

      Comment

      • dbpokorny@gmail.com

        #4
        Re: How to make a function associated with a class?

        On Jul 1, 1:43 pm, Kurda Yon <kurda...@yahoo .comwrote:
        Hi,
        >
        I have a class called "vector". And I would like to define a function
        "dot" which would return a dot product of any two "vectors". I want
        to call this function as follow: dot(x,y).
        >
        Well, I can define a functions "dot" outside the class and it works
        exactly as I want. However, the problem is that this function is not
        associated with the class (like methods a method of the class).
        >
        For example, if I call "x.calc()" or "y.calc()", python will execute
        different methods if "x" and "y" belongs to different classes. I want
        to have the same with my "dot" function. I.e. I want it calculates the
        dot product ONLY IF the both arguments of that function belong to the
        "vector" class.
        >
        Is it possible?
        >
        Thank you in advance.
        It sounds like you are talking about data-directed programming (see
        http://mitpress.mit.edu/sicp/full-te...l#%_sec_2.4.3).
        Basically you have two options:

        def dot(x,y):
        if isinstance(x,Ve ctor) and isintance(y,Vec tor):
        ...
        raise TypeError("..." )

        which quickly breaks down in a mess of if-then clauses when you want
        to expand the dot function to handle other datatypes, or you create a
        table and populate it with entries like this
        dispatch_table[('dot','Vector' ,'Vector')] = Vector.dot # this has to
        be declared @staticmethod in class Vector
        dispatch_table[('dot','str','s tr')] = operator.add # borrowed from PHP
        dispatch_table[('mul',Matrix,M atrix)] = Matrix.mul

        You now have to write something like this (this isn't even valid
        Python code, but hopefully you get the idea)

        def generic_functio n(name):
        def exec_generic_fu nction(*args):
        f = dispatch_table. get((name, *(type(arg).__n ame__ for arg in
        args)),None)
        if f == None:
        raise TypeError('...' )
        return f(*args)
        return exec_generic_fu nction

        dot = generic_functio n('dot')

        # NB: (a, *b) means (a,) + b until the generalized *-unpacking syntax
        is accepted

        This is essentially a translation into Python of the content of the
        link.

        Neither of these options are great (and the latter is marginal at
        best) if you care about performance (but maybe it will all become C
        anyway so you don't care). If you want to do it the Python way, use
        __mul__.

        Cheers,
        David

        Comment

        • dbpokorny@gmail.com

          #5
          Re: How to make a function associated with a class?

          On Jul 1, 2:24 pm, Kurda Yon <kurda...@yahoo .comwrote:
          >
          By the way, "type(self) " returns the name of the class to which the
          "self" belongs?
          Does "instance" return "true" if the first argument belongs to the
          class whose name is given in the second argument?
          $ python
          Python 2.5.1 (r251:54863, Oct 30 2007, 13:54:11)
          [GCC 4.1.2 20070925 (Red Hat 4.1.2-33)] on linux2
          Type "help", "copyright" , "credits" or "license" for more information.
          >>help(type)
          [...]
          >>help(isinstan ce)
          [...]

          Comment

          • John Roth

            #6
            Re: How to make a function associated with a class?

            On Jul 1, 2:43 pm, Kurda Yon <kurda...@yahoo .comwrote:
            Hi,
            >
            I have a class called "vector". And I would like to define a function
            "dot" which would return a dot product of any two "vectors". I want
            to call this function as follow: dot(x,y).
            >
            Well, I can define a functions "dot" outside the class and it works
            exactly as I want. However, the problem is that this function is not
            associated with the class (like methods a method of the class).
            >
            For example, if I call "x.calc()" or "y.calc()", python will execute
            different methods if "x" and "y" belongs to different classes. I want
            to have the same with my "dot" function. I.e. I want it calculates the
            dot product ONLY IF the both arguments of that function belong to the
            "vector" class.
            >
            Is it possible?
            >
            Thank you in advance.
            If I understand what you want, you could do it the same way most of
            the other functions are implemented. There's a function, and then each
            class which has the behavior has a private (actually a system) method
            that implements it.

            The general pattern is to get the class for the first operand, check
            to see if it has the implementation method, and call it if present. If
            it doesn't, get the class for the other operand, check and if it has
            the method call it with the operands reversed.

            Then if it isn't in either, you can look the actual implementation
            method up in a table. When all else fails, raise a type error.

            HTH

            John Roth

            Comment

            • Bruno Desthuilliers

              #7
              Re: How to make a function associated with a class?

              Kurda Yon a écrit :
              On Jul 1, 5:01 pm, "bruno.desthuil li...@gmail.com "
              <bruno.desthuil li...@gmail.com wrote:
              >On 1 juil, 22:43, Kurda Yon <kurda...@yahoo .comwrote:
              >>
              >>
              >>
              >>Hi,
              >>I have a class called "vector". And I would like to define a function
              >>"dot" which would return a dot product of any two "vectors". I want
              >>to call this function as follow: dot(x,y).
              >>Well, I can define a functions "dot" outside the class and it works
              >>exactly as I want. However, the problem is that this function is not
              >>associated with the class (like methods a method of the class).
              >>For example, if I call "x.calc()" or "y.calc()", python will execute
              >>different methods if "x" and "y" belongs to different classes. I want
              >>to have the same with my "dot" function. I.e. I want it calculates the
              >>dot product ONLY IF the both arguments of that function belong to the
              >>"vector" class.
              >>Is it possible?
              >You don't need to make dot() a method of your Vector class to have
              >this behaviour, and making it a method of the Vector class isn't
              >enough to have this behaviour.
              >>
              >The simplest solution would be:
              >>
              >class Vector(object):
              > def dot(self, other):
              > if not isinstance(othe r, type(self)):
              > raise TypeError("can only calculate the dot product of two
              >vectors")
              > # do the job here and return what's appropriate
              >>
              >Now since it's a binary operator, you might as well implement it as
              >such:
              >>
              >class Vector(object):
              > def __mul__(self, other):
              > if not isinstance(othe r, type(self)):
              > raise TypeError("can only calculate the dot product of two
              >vectors")
              > # do the job here and return what's appropriate
              >>
              >Then use it as doproduct = vector1 * vector2
              >>
              >HTH
              >
              As far as I understood, In the first case, you gave, I need to call
              the function as follows "x.dot(y)". In the second case I need to call
              the function as follows "x*y". But I want to call the function as
              follows "dot(x,y)".
              I tought you could figure it out by yourself from the above examples.

              By the way, "type(self) " returns the name of the class to which the
              "self" belongs?
              Nope, it returns the class object (for new-style classes at least).
              Does "instance" return "true" if the first argument belongs to the
              class whose name
              Python's classes are objects. type() returns a class object (or a type
              object for old-style classes IIRC), and isinstance() takes a class or
              style object (or a tuple of class / type objects) as second argument.
              is given in the second argument?
              isinstance() is documented, you know ? As well as type() FWIW. What
              about first looking up the fine manual, then come back if there's
              something you have problem with ?-)

              Comment

              • David C. Ullrich

                #8
                Re: How to make a function associated with a class?

                In article
                <0d9c534b-8720-4363-b3e5-eb546dd3637c@8g 2000hse.googleg roups.com>,
                Kurda Yon <kurdayon@yahoo .comwrote:
                On Jul 1, 5:01 pm, "bruno.desthuil li...@gmail.com "
                <bruno.desthuil li...@gmail.com wrote:
                On 1 juil, 22:43, Kurda Yon <kurda...@yahoo .comwrote:


                Hi,
                I have a class called "vector". And I would like to define a function
                "dot" which would return a dot product of any two "vectors". I want
                to call this function as follow: dot(x,y).
                Well, I can define a functions "dot" outside the class and it works
                exactly as I want. However, the problem is that this function is not
                associated with the class (like methods a method of the class).
                For example, if I call "x.calc()" or "y.calc()", python will execute
                different methods if "x" and "y" belongs to different classes. I want
                to have the same with my "dot" function. I.e. I want it calculates the
                dot product ONLY IF the both arguments of that function belong to the
                "vector" class.
                Is it possible?
                You don't need to make dot() a method of your Vector class to have
                this behaviour, and making it a method of the Vector class isn't
                enough to have this behaviour.

                The simplest solution would be:

                class Vector(object):
                def dot(self, other):
                if not isinstance(othe r, type(self)):
                raise TypeError("can only calculate the dot product of two
                vectors")
                # do the job here and return what's appropriate

                Now since it's a binary operator, you might as well implement it as
                such:

                class Vector(object):
                def __mul__(self, other):
                if not isinstance(othe r, type(self)):
                raise TypeError("can only calculate the dot product of two
                vectors")
                # do the job here and return what's appropriate

                Then use it as doproduct = vector1 * vector2

                HTH
                >
                As far as I understood, In the first case, you gave, I need to call
                the function as follows "x.dot(y)". In the second case I need to call
                the function as follows "x*y". But I want to call the function as
                follows "dot(x,y)".
                You want to say dot(x,y), but to have the actual behavior
                determined by the class of which x and y are instances?
                You could do this:

                def dot(x,y):
                return x.dot(y)

                and now give Vector an appropriate dot(self, other) method.
                By the way, "type(self) " returns the name of the class to which the
                "self" belongs?
                Does "instance" return "true" if the first argument belongs to the
                class whose name is given in the second argument?
                --
                David C. Ullrich

                Comment

                Working...