python assignment

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

    python assignment

    without stirring the pot too much --

    could someone please point me to whatever documentation exists on the
    philosophy, semantics, and practical implications of how Python
    implements the assignment operator? So far I can't find much useful
    in the regular documentation. I understand the basic concept that
    names are bound to objects which exist on the heap, but that still
    doesn't explain why a = b doesn't _always_ cause a to point to the
    same object as b. What determines when the object in question is
    copied? What determines when a future maniplulation of the variable
    will cause it to point to an object that is already referenced by
    another variable? (see code below for an example).

    What I need is an exact and unambiguous algorithm for determining when
    an assignment will change the id of the variable (or should I say,
    when the evaluation of an expression will cause a new object to be
    created). Some of the issues involved can be discerned from the
    following session:
    [color=blue][color=green][color=darkred]
    >>> a = 1
    >>> b = a
    >>> a is b[/color][/color][/color]
    True[color=blue][color=green][color=darkred]
    >>> a += 1
    >>> a -= 1
    >>> a is b[/color][/color][/color]
    True[color=blue][color=green][color=darkred]
    >>> a = 1.0
    >>> b = a
    >>> a is b[/color][/color][/color]
    True[color=blue][color=green][color=darkred]
    >>> a += 1
    >>> a -= 1
    >>> a is b[/color][/color][/color]
    False[color=blue][color=green][color=darkred]
    >>> a == b[/color][/color][/color]
    True
  • dan

    #2
    Re: python assignment

    Ok, thanks for the responses. I think I 'get' it now. However I do
    think it would be an excellent idea to have a bit of exposition on
    this subject in the Python tutorial, or perhaps in a separate section.
    It's not really hard to understand once you realize what's going on,
    but I suspect it causes no end of confusion for both new programmers
    and old (those used to langs such as C++).

    Here's a better example of how a newbie can get confused:
    [color=blue][color=green][color=darkred]
    >>> a = (1,2) #a is a tuple
    >>> b = a #b & a now point to same object on heap
    >>> a += (3,) #tuples are immutable so += returns a new one
    >>> b == a #b points to old, a points to new[/color][/color][/color]
    False[color=blue][color=green][color=darkred]
    >>> a = [1,2] #a is a list
    >>> b = a #a & b point to same object again
    >>> a += [3] #a is mutable, so += mutates it
    >>> b == a #of course[/color][/color][/color]
    True[color=blue][color=green][color=darkred]
    >>> a = a + [4] #hmm... one *might* think this is eqiv. to a += [4]
    >>> a == b[/color][/color][/color]
    False #but NOOO!![color=blue][color=green][color=darkred]
    >>> a[/color][/color][/color]
    [1, 2, 3, 4][color=blue][color=green][color=darkred]
    >>> b[/color][/color][/color]
    [1, 2, 3]

    Now that I understand what's happening, it makes sense, but initially
    this sort of behavior was quite mysterious.

    -dbm

    danbmil99@yahoo .com (dan) wrote in message news:<fbf8d8f2. 0307221659.1dd1 ac77@posting.go ogle.com>...[color=blue]
    > without stirring the pot too much --
    >
    > could someone please point me to whatever documentation exists on the
    > philosophy, semantics, and practical implications of how Python
    > implements the assignment operator? So far I can't find much useful
    > in the regular documentation. I understand the basic concept that
    > names are bound to objects which exist on the heap, but that still
    > doesn't explain why a = b doesn't _always_ cause a to point to the
    > same object as b. What determines when the object in question is
    > copied? What determines when a future maniplulation of the variable
    > will cause it to point to an object that is already referenced by
    > another variable? (see code below for an example).
    >
    > What I need is an exact and unambiguous algorithm for determining when
    > an assignment will change the id of the variable (or should I say,
    > when the evaluation of an expression will cause a new object to be
    > created). Some of the issues involved can be discerned from the
    > following session:
    >[color=green][color=darkred]
    > >>> a = 1
    > >>> b = a
    > >>> a is b[/color][/color]
    > True[color=green][color=darkred]
    > >>> a += 1
    > >>> a -= 1
    > >>> a is b[/color][/color]
    > True[color=green][color=darkred]
    > >>> a = 1.0
    > >>> b = a
    > >>> a is b[/color][/color]
    > True[color=green][color=darkred]
    > >>> a += 1
    > >>> a -= 1
    > >>> a is b[/color][/color]
    > False[color=green][color=darkred]
    > >>> a == b[/color][/color]
    > True[/color]

    Comment

    • Juha Autero

      #3
      Re: python assignment

      "Tim Peters" <tim.one@comcas t.net> writes:
      [color=blue]
      > It would be very unusual (because bad design) for the __iadd__
      > method of a mutable type to return a pre-existing object, though.[/color]

      I'm confused. I thought that the idea of __iadd__ is that for
      *mutable* types it modifies existing object instead of returning new
      one. So, was that a typo or are Python lists just bad desing:

      [color=blue][color=green][color=darkred]
      >>> l=[]
      >>> f=l
      >>> f+=[1]
      >>> f[/color][/color][/color]
      [1][color=blue][color=green][color=darkred]
      >>> l[/color][/color][/color]
      [1]

      --
      Juha Autero

      Eschew obscurity!


      Comment

      • Grant Edwards

        #4
        Re: python assignment

        In article <slrnbhrqtj.9jf .bignose-hates-spam@iris.polar .local>, Ben Finney wrote:
        [color=blue][color=green]
        >> What I need is an exact and unambiguous algorithm for determining when
        >> an assignment will change the id of the variable[/color]
        >
        > As I understand it, this is specific to the implementation of each type.
        > The only sensible way to code is as if the identity of an object, on
        > assignment, were completely unpredictable.
        >
        > The examples you gave showed that integers share identity with other
        > integers of the same value, while floats do not.[/color]

        I believe that's only true for small integers, isn't it?

        --
        Grant Edwards grante Yow! I want to TAKE IT
        at HOME and DRESS IT UP in
        visi.com HOT PANTS!!

        Comment

        • Peter Hansen

          #5
          Re: python assignment

          Grant Edwards wrote:[color=blue]
          >
          > In article <slrnbhrqtj.9jf .bignose-hates-spam@iris.polar .local>, Ben Finney wrote:
          >[color=green][color=darkred]
          > >> What I need is an exact and unambiguous algorithm for determining when
          > >> an assignment will change the id of the variable[/color]
          > >
          > > As I understand it, this is specific to the implementation of each type.
          > > The only sensible way to code is as if the identity of an object, on
          > > assignment, were completely unpredictable.
          > >
          > > The examples you gave showed that integers share identity with other
          > > integers of the same value, while floats do not.[/color]
          >
          > I believe that's only true for small integers, isn't it?[/color]

          Google finds "LOADI - a fast load instruction for small positive integers
          (those referenced by the small_ints array in intobject.c)" and checking
          that file is left as an exercise to the reader. I'm going to blindly
          assume this is directly related to the issue in question... ;-)

          -Peter

          Comment

          • Skip Montanaro

            #6
            Re: python assignment

            [color=blue][color=green][color=darkred]
            >> > The examples you gave showed that integers share identity with other
            >> > integers of the same value, while floats do not.[/color][/color][/color]
            [color=blue][color=green]
            >> I believe that's only true for small integers, isn't it?[/color][/color]

            Peter> Google finds "LOADI - a fast load instruction for small positive
            Peter> integers (those referenced by the small_ints array in
            Peter> intobject.c)"

            LOADI was an instruction I implemented a few years ago when investigating
            bytecode optimization. It was never added to the Python virtual machine
            (ceval.c).

            Skip

            Comment

            • Jim Richardson

              #7
              Shallow vs Deep copies [was Re: python assignment]

              -----BEGIN PGP SIGNED MESSAGE-----
              Hash: SHA1

              On Tue, 22 Jul 2003 22:46:56 -0400,
              Tim Peters <tim.one@comcas t.net> wrote:
              [color=blue]
              > The rule that the object in question is never copied. There are no
              > exceptions to this. Copying an object requires invoking some method
              > of the object, or applying some function to the object. For example,
              > d.copy() returns a (shallow) copy of a dict d, and L[:] returns a
              > (shallow) copy of a list L.[/color]


              To clarify for me please.

              A shallow copy of an object, returns an object that contains references
              to objects within the copied object, yes?

              so a list consisting of [1,2,a,"a"] when copied shallowly, will return
              exactly that, but when copied deeply, will reture [1,2,"whatever a
              points to","a"] yes?

              If I understand the above correctly.... how deep does a deep copy go?
              can you vary the depth? Or is it binary, shallow or deep?

              Thanks.

              -----BEGIN PGP SIGNATURE-----
              Version: GnuPG v1.2.2 (GNU/Linux)

              iD8DBQE/Hr9Bd90bcYOAWPY RAnaYAKDDRFGR6F G3ytgN2dwf7w1sh DND3QCgs33B
              8jNxKhsF1Ti7bkb PzbCxEx4=
              =6a1K
              -----END PGP SIGNATURE-----

              --
              Jim Richardson http://www.eskimo.com/~warlock

              Linux, because eventually, you grow up enough to be trusted with a fork()

              Comment

              • Erik Max Francis

                #8
                Re: Shallow vs Deep copies [was Re: python assignment]

                Jim Richardson wrote:
                [color=blue]
                > A shallow copy of an object, returns an object that contains
                > references
                > to objects within the copied object, yes?
                >
                > so a list consisting of [1,2,a,"a"] when copied shallowly, will return
                > exactly that, but when copied deeply, will reture [1,2,"whatever a
                > points to","a"] yes?[/color]

                No, that's what the first list already consists of:
                [color=blue][color=green][color=darkred]
                >>> a = "whatever a points to"
                >>> l1 = [1, 2, a, "a"]
                >>> l1[/color][/color][/color]
                [1, 2, 'whatever a points to', 'a']

                A shallow copy makes a new object of the object passed in, and maintains
                the same reference. A deep copy makes a new object, _and_ a new object
                of all references it contains, and on down the line.

                The difference between shallow and deep copying is not apparent when
                you're talking about immutable objects, since immutable objects need not
                ever be literally copied. Consider a simpler case of a list containing
                a single element, which is an instance of a custom class:
                [color=blue][color=green][color=darkred]
                >>> class C: pass[/color][/color][/color]
                ....[color=blue][color=green][color=darkred]
                >>> c = C()
                >>> x = [c]
                >>> y = copy.copy(x)
                >>> x is y[/color][/color][/color]
                0[color=blue][color=green][color=darkred]
                >>> x[0] is y[0][/color][/color][/color]
                1[color=blue][color=green][color=darkred]
                >>> z = copy.deepcopy(x )
                >>> x is z[/color][/color][/color]
                0[color=blue][color=green][color=darkred]
                >>> x[0] is z[0][/color][/color][/color]
                0[color=blue][color=green][color=darkred]
                >>> x[0][/color][/color][/color]
                <__main__.C instance at 0x810ba8c>[color=blue][color=green][color=darkred]
                >>> z[0][/color][/color][/color]
                <__main__.C instance at 0x814c9fc>

                Shallow copying makes a duplicate of the parent object. Deep copying
                makes a duplicate of everything.

                --
                Erik Max Francis && max@alcyone.com && http://www.alcyone.com/max/
                __ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
                / \ Of war men ask the outcome, not the cause.
                \__/ Seneca

                Comment

                • Terry Reedy

                  #9
                  Re: Shallow vs Deep copies [was Re: python assignment]


                  "Erik Max Francis" <max@alcyone.co m> wrote in message
                  news:3F1EDFA0.E D78E04F@alcyone .com...
                  [color=blue]
                  > immutable objects need not ever be literally copied[/color]
                  [color=blue]
                  > Shallow copying makes a duplicate of the parent object. Deep[/color]
                  copying[color=blue]
                  > makes a duplicate of everything.[/color]

                  To be more exact, because first statement is true,
                  second_statemen t.replace('ever ything', 'all mutables'),
                  which is to say, 'as much as needed'.
                  [color=blue][color=green][color=darkred]
                  >>> import copy
                  >>> l1=[(),[]]
                  >>> l2=copy.deepcop y(l1)
                  >>> for i in l1+l2: print id(i)[/color][/color][/color]
                  ....
                  7669904
                  8422784
                  7669904 #same ()
                  8428448 #different []

                  Terry J. Reedy



                  Comment

                  Working...