Overloading assignment operator

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Achim Domma

    #1

    Overloading assignment operator

    Hi,

    I want to use Python to script some formulas in my application. The user
    should be able to write something like

    A = B * C

    where A,B,C are instances of some wrapper classes. Overloading * is no
    problem but I cannot overload the assignment of A. I understand that
    this is due to the nature of Python, but is there a trick to work around
    this?
    All I'm interested in is a clean syntax to script my app. Any ideas are
    very welcome.

    regards,
    Achim
  • Peter Otten

    #2
    Re: Overloading assignment operator

    Achim Domma wrote:
    I want to use Python to script some formulas in my application. The user
    should be able to write something like
    >
    A = B * C
    >
    where A,B,C are instances of some wrapper classes. Overloading * is no
    problem but I cannot overload the assignment of A. I understand that
    this is due to the nature of Python, but is there a trick to work around
    this?
    >>class D(dict):
    .... def __setitem__(sel f, key, value):
    .... print key, "<--", value
    .... dict.__setitem_ _(self, key, value)
    ....
    >>namespace = D(B=42, C=24)
    >>exec "A = B * C" in namespace
    A <-- 1008

    Peter

    Comment

    • Paul McGuire

      #3
      Re: Overloading assignment operator

      On Jan 23, 12:24 pm, Achim Domma <d...@procoders .netwrote:
      Hi,
      >
      I want to use Python to script some formulas in my application. The user
      should be able to write something like
      >
      A = B * C
      >
      where A,B,C are instances of some wrapper classes. Overloading * is no
      problem but I cannot overload the assignment of A. I understand that
      this is due to the nature of Python, but is there a trick to work around
      this?
      All I'm interested in is a clean syntax to script my app. Any ideas are
      very welcome.
      >
      regards,
      Achim
      Simple option: how do you feel about using '<<=' instead of '=' (by
      defining __ilshift__)? This gives you:

      A <<= B * C

      (looks sort of like "injecting" the result of B times C into A)

      More complicated option: embed an expression/assignment parser into
      your app. You can get a jump on this using some of the examples that
      come with pyparsing (can check these out online at
      http://pyparsing.wikispaces.com/Examples - look at fourFn.py and
      simpleArith.py) .

      -- Paul

      Comment

      • Erik Max Francis

        #4
        Re: Overloading assignment operator

        Achim Domma wrote:
        I want to use Python to script some formulas in my application. The user
        should be able to write something like
        >
        A = B * C
        >
        where A,B,C are instances of some wrapper classes. Overloading * is no
        problem but I cannot overload the assignment of A. I understand that
        this is due to the nature of Python, but is there a trick to work around
        this?
        All I'm interested in is a clean syntax to script my app. Any ideas are
        very welcome.
        Are you sure you even need to do that?
        >>class C:
        .... def __init__(self, x):
        .... self.x = x
        .... def __mul__(self, other):
        .... return C(self.x*other. x)
        ....
        >>result = C(2)*C(3)
        >>print result
        <__main__.C instance at 0x402e13ec>
        >>result.x
        6

        --
        Erik Max Francis && max@alcyone.com && http://www.alcyone.com/max/
        San Jose, CA, USA && 37 20 N 121 53 W && AIM, Y!M erikmaxfrancis
        Life is something to do when you can't get to sleep.
        -- Fran Lebowitz

        Comment

        • Kay Schluehr

          #5
          Re: Overloading assignment operator


          Achim Domma schrieb:
          Hi,
          >
          I want to use Python to script some formulas in my application. The user
          should be able to write something like
          >
          A = B * C
          >
          where A,B,C are instances of some wrapper classes. Overloading * is no
          problem but I cannot overload the assignment of A. I understand that
          this is due to the nature of Python, but is there a trick to work around
          this?
          Not that I know about it but what shall be the behaviour of assignment
          when being overloaded?

          Kay

          Comment

          • Steven D'Aprano

            #6
            Re: Overloading assignment operator

            On Tue, 23 Jan 2007 19:42:01 +0100, Peter Otten wrote:
            Achim Domma wrote:
            >
            >I want to use Python to script some formulas in my application. The user
            >should be able to write something like
            >>
            >A = B * C
            >>
            >where A,B,C are instances of some wrapper classes. Overloading * is no
            >problem but I cannot overload the assignment of A. I understand that
            >this is due to the nature of Python, but is there a trick to work around
            >this?
            >
            >>>class D(dict):
            ... def __setitem__(sel f, key, value):
            ... print key, "<--", value
            ... dict.__setitem_ _(self, key, value)
            ...
            >>>namespace = D(B=42, C=24)
            >>>exec "A = B * C" in namespace
            A <-- 1008
            Very clever, except:

            (1) The Original Poster's requirement was for a "clean syntax" and
            'exec "A = B * C" in namespace' is anything but a clean syntax.

            (2) The O.P. specifies that the syntax is for use by his users. We don't
            know who these users are, but can you see users getting this right and not
            ignoring the namespace argument?

            (3) Even if they do use the namespace argument, how hard is it for the
            users to break the security of your exec?
            >>exec "A = B * C;import os;os.system('l s -l break-something')" in namespace
            A <-- 1008
            os <-- <module 'os' from '/usr/lib/python2.4/os.pyc'>
            -rw-rw-r-- 1 steve steve 0 Jan 24 08:27 break-something

            Using exec on user-supplied data is just begging to be p0wned.


            --
            Steven.

            Comment

            • Achim Domma

              #7
              Re: Overloading assignment operator

              Paul McGuire wrote:
              Simple option: how do you feel about using '<<=' instead of '=' (by
              defining __ilshift__)? This gives you:
              >
              A <<= B * C
              >
              (looks sort of like "injecting" the result of B times C into A)
              Thanks! That is exactly the kind of solution I was looking for! :-)

              Achim

              Comment

              • Peter Otten

                #8
                Re: Overloading assignment operator

                Steven D'Aprano wrote:
                On Tue, 23 Jan 2007 19:42:01 +0100, Peter Otten wrote:
                >
                >Achim Domma wrote:
                >>
                >>I want to use Python to script some formulas in my application. The user
                >>should be able to write something like
                >>>
                >>A = B * C
                >>>
                >>where A,B,C are instances of some wrapper classes. Overloading * is no
                >>problem but I cannot overload the assignment of A. I understand that
                >>this is due to the nature of Python, but is there a trick to work around
                >>this?
                >>
                >>>>class D(dict):
                >... def __setitem__(sel f, key, value):
                >... print key, "<--", value
                >... dict.__setitem_ _(self, key, value)
                >...
                >>>>namespace = D(B=42, C=24)
                >>>>exec "A = B * C" in namespace
                >A <-- 1008
                >
                Very clever, except:
                >
                (1) The Original Poster's requirement was for a "clean syntax" and
                'exec "A = B * C" in namespace' is anything but a clean syntax.
                >
                (2) The O.P. specifies that the syntax is for use by his users. We don't
                know who these users are, but can you see users getting this right and not
                ignoring the namespace argument?
                I thought he might hide everything but the expression

                A = B * C

                from the user.
                (3) Even if they do use the namespace argument, how hard is it for the
                users to break the security of your exec?
                >
                >>>exec "A = B * C;import os;os.system('l s -l break-something')" in
                >>>namespace
                A <-- 1008
                os <-- <module 'os' from '/usr/lib/python2.4/os.pyc'>
                -rw-rw-r-- 1 steve steve 0 Jan 24 08:27 break-something
                >
                Using exec on user-supplied data is just begging to be p0wned.
                Yes. Unless the application is deployed to the user's machine, in which case
                he has more straightforward methods to destroy his own data.

                Peter

                Comment

                • Russ

                  #9
                  Re: Overloading assignment operator

                  Achim Domma wrote:
                  Hi,
                  >
                  I want to use Python to script some formulas in my application. The user
                  should be able to write something like
                  >
                  A = B * C
                  >
                  where A,B,C are instances of some wrapper classes. Overloading * is no
                  problem but I cannot overload the assignment of A. I understand that
                  this is due to the nature of Python, but is there a trick to work around
                  this?
                  All I'm interested in is a clean syntax to script my app. Any ideas are
                  very welcome.
                  >
                  regards,
                  Achim
                  Why do you need to overload assignment anyway? If you overloaded "*"
                  properly, it should return
                  the result you want, which you then "assign" to A as usual. Maybe I'm
                  missing something.

                  Comment

                  • Steven D'Aprano

                    #10
                    Re: Overloading assignment operator

                    On Tue, 23 Jan 2007 18:07:55 -0800, Russ wrote:
                    Achim Domma wrote:
                    >Hi,
                    >>
                    >I want to use Python to script some formulas in my application. The user
                    >should be able to write something like
                    >>
                    >A = B * C
                    >>
                    >where A,B,C are instances of some wrapper classes. Overloading * is no
                    >problem but I cannot overload the assignment of A. I understand that
                    >this is due to the nature of Python, but is there a trick to work around
                    >this?
                    >All I'm interested in is a clean syntax to script my app. Any ideas are
                    >very welcome.
                    >>
                    >regards,
                    >Achim
                    >
                    Why do you need to overload assignment anyway? If you overloaded "*"
                    properly, it should return
                    the result you want, which you then "assign" to A as usual. Maybe I'm
                    missing something.
                    One common reason for overriding assignment is so the left-hand-side of
                    the assignment can choose the result type. E.g. if Cheddar, Swiss and
                    Wensleydale are three custom classes, mutually compatible for
                    multiplication:

                    B = Cheddar() # B is type Cheddar
                    C = Swiss() # C is type Swiss
                    # without overloading assignment
                    A = B * C # A is (possibly) Cheddar since B.__mul__ is called first
                    A = C * B # A is (possibly) Swiss since C.__mul__ is called first
                    # with (hypothetical) assignment overloading
                    A = B * C # A is type Wensleydale since A.__assign__ is called

                    Except, of course, there is no assignment overloading in Python. There
                    can't be, because A may not exist when the assignment is performed, and
                    if it does exist it might be a complete different type.

                    Instead, you can do something like this:

                    A = Wensleydale(B) * Wensleydale(C)

                    or

                    A = Wensleydale(B * C)




                    --
                    Steven D'Aprano

                    Comment

                    • John Pye

                      #11
                      Re: Overloading assignment operator

                      Hi thre,

                      On Jan 24, 5:24 am, Achim Domma <d...@procoders .netwrote:
                      I want to use Python to script some formulas in my application.
                      Depending on what you're trying to do, you might possibly find it
                      useful to lake a look at the approach used by PyGINAC, which is a
                      symbolic algebra system (in C++) wrapped with some clever python
                      bindings:



                      Hope that helps,
                      JP

                      Comment

                      • J. Clifford Dyer

                        #12
                        Re: Overloading assignment operator

                        Steven D'Aprano wrote:
                        On Tue, 23 Jan 2007 18:07:55 -0800, Russ wrote:
                        >
                        >Achim Domma wrote:
                        >>Hi,
                        >>>
                        >>I want to use Python to script some formulas in my application. The user
                        >>should be able to write something like
                        >>>
                        >>A = B * C
                        >>>
                        >>where A,B,C are instances of some wrapper classes. Overloading * is no
                        >>problem but I cannot overload the assignment of A. I understand that
                        >>this is due to the nature of Python, but is there a trick to work around
                        >>this?
                        >>All I'm interested in is a clean syntax to script my app. Any ideas are
                        >>very welcome.
                        >>>
                        >>regards,
                        >>Achim
                        >Why do you need to overload assignment anyway? If you overloaded "*"
                        >properly, it should return
                        >the result you want, which you then "assign" to A as usual. Maybe I'm
                        >missing something.
                        >
                        One common reason for overriding assignment is so the left-hand-side of
                        the assignment can choose the result type. E.g. if Cheddar, Swiss and
                        Wensleydale are three custom classes, mutually compatible for
                        multiplication:
                        >
                        B = Cheddar() # B is type Cheddar
                        C = Swiss() # C is type Swiss
                        # without overloading assignment
                        A = B * C # A is (possibly) Cheddar since B.__mul__ is called first
                        A = C * B # A is (possibly) Swiss since C.__mul__ is called first
                        # with (hypothetical) assignment overloading
                        A = B * C # A is type Wensleydale since A.__assign__ is called
                        >
                        Except, of course, there is no assignment overloading in Python. There
                        can't be, because A may not exist when the assignment is performed, and
                        if it does exist it might be a complete different type.
                        >
                        Instead, you can do something like this:
                        >
                        A = Wensleydale(B) * Wensleydale(C)
                        >
                        or
                        >
                        A = Wensleydale(B * C)
                        >
                        >
                        >
                        >
                        I think that's the first time I've actually seen someone use a Monty
                        Python theme for a python example, and I must say, I like it. However,
                        "We are all out of Wensleydale."

                        Cheers,
                        Cliff

                        Comment

                        • Michael Spencer

                          #13
                          Re: Overloading assignment operator

                          J. Clifford Dyer wrote:
                          I think that's the first time I've actually seen someone use a Monty
                          Python theme for a python example, and I must say, I like it. However,
                          "We are all out of Wensleydale."
                          >
                          Cheers,
                          Cliff
                          Oh, then you clearly don't waste nearly enough time on this newsgroup ;-)









                          Idly yours,

                          Michael

                          Comment

                          Working...