The del statement

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

    The del statement

    One of the few Python constructs that feels less elegant than
    necessary to me is the del statement. For one thing, it is overloaded
    to mean three different things:
    (1) del x: Remove x from the current namespace
    (2) del x[i]: Equivalent to x.__delitem__(i )
    (3) del x.a: Equivalent to x.__delattr__(' a') (or delattr(x,'a'))

    (1) is useful, or even necessary, at least as long as there are only
    two namespaces (local and global) instead of a separate namespace per
    block, so that's ok for now. The other two though, don't justify IMO a
    separate statement.

    I would strongly prefer (2) to be implemented by a normal method
    instead of a special syntax and method. See the inconsistency:
    s = ['a', 'b']
    s.pop(0)
    del s[0]

    Likewise for dicts. Why not s.del(0) ? And just in case someone argues
    "for the same reason we have __getitem__ and __setitem__", it is not
    the same; the syntax for get/set (s[0], s[0] = 'a') doesn't introduce
    a new keyword (or overload an existing one), it is pretty intuitive
    and used across many languages. As for (3), it is pretty uncommon to
    deserve its own syntax; delattr() or directly modifying self.__dict__
    are good enough.

    I understand that no more proposals are accepted for Python 3 but it
    looks like a missed opportunity to make the language a bit simpler and
    more consistent. Anyone else have an opinion on this?

    George
  • Arnaud Delobelle

    #2
    Re: The del statement



    George Sakkis wrote:
    One of the few Python constructs that feels less elegant than
    necessary to me is the del statement. For one thing, it is overloaded
    to mean three different things:
    (1) del x: Remove x from the current namespace
    (2) del x[i]: Equivalent to x.__delitem__(i )
    (3) del x.a: Equivalent to x.__delattr__(' a') (or delattr(x,'a'))
    Note that the 'X = Y' construct has the corresponding three meanings:

    (1) x = 4 # Bind x to 4 in the 'current namespace'
    (2) x[i] = 4 # equivalent to x.__setitem__(i , 4)
    (3) x.a = 4 # Equivalent to x.__setattr__(' a', 4)

    What conclusion should we draw from that?

    --
    Arnaud

    Comment

    • Duncan Booth

      #3
      Re: The del statement

      Arnaud Delobelle <arnodel@google mail.comwrote:
      >
      >
      George Sakkis wrote:
      >One of the few Python constructs that feels less elegant than
      >necessary to me is the del statement. For one thing, it is overloaded
      >to mean three different things:
      >(1) del x: Remove x from the current namespace
      >(2) del x[i]: Equivalent to x.__delitem__(i )
      >(3) del x.a: Equivalent to x.__delattr__(' a') (or delattr(x,'a'))
      >
      Note that the 'X = Y' construct has the corresponding three meanings:
      >
      (1) x = 4 # Bind x to 4 in the 'current namespace'
      (2) x[i] = 4 # equivalent to x.__setitem__(i , 4)
      (3) x.a = 4 # Equivalent to x.__setattr__(' a', 4)
      I think you both missed a case:

      (1b) global x; del x # Remove x from global namespace
      (1b) global x; x = 4 # Bind x to 4 in the global namespace
      What conclusion should we draw from that?
      That Python is simple and consistent.

      Comment

      • Arnaud Delobelle

        #4
        Re: The del statement



        Duncan Booth wrote:
        Arnaud Delobelle <arnodel@google mail.comwrote:
        >


        George Sakkis wrote:
        One of the few Python constructs that feels less elegant than
        necessary to me is the del statement. For one thing, it is overloaded
        to mean three different things:
        (1) del x: Remove x from the current namespace
        (2) del x[i]: Equivalent to x.__delitem__(i )
        (3) del x.a: Equivalent to x.__delattr__(' a') (or delattr(x,'a'))
        Note that the 'X = Y' construct has the corresponding three meanings:

        (1) x = 4 # Bind x to 4 in the 'current namespace'
        (2) x[i] = 4 # equivalent to x.__setitem__(i , 4)
        (3) x.a = 4 # Equivalent to x.__setattr__(' a', 4)
        >
        I think you both missed a case:
        >
        (1b) global x; del x # Remove x from global namespace
        (1b) global x; x = 4 # Bind x to 4 in the global namespace
        This is why you put 'current namespace' in quotes! But all three of
        us missed the case:

        (1-3000) What about nonlocal?
        That Python is simple and consistent.
        Seems reasonable to me.

        --
        Arnaud

        Comment

        • Duncan Booth

          #5
          Re: The del statement

          Arnaud Delobelle <arnodel@google mail.comwrote:
          >
          >
          Duncan Booth wrote:
          >Arnaud Delobelle <arnodel@google mail.comwrote:
          >>
          >
          >
          George Sakkis wrote:
          >One of the few Python constructs that feels less elegant than
          >necessary to me is the del statement. For one thing, it is
          overloaded
          >to mean three different things:
          >(1) del x: Remove x from the current namespace
          >(2) del x[i]: Equivalent to x.__delitem__(i )
          >(3) del x.a: Equivalent to x.__delattr__(' a') (or delattr(x,'a'))
          >
          Note that the 'X = Y' construct has the corresponding three
          meanings:
          >
          (1) x = 4 # Bind x to 4 in the 'current namespace'
          (2) x[i] = 4 # equivalent to x.__setitem__(i , 4)
          (3) x.a = 4 # Equivalent to x.__setattr__(' a', 4)
          >>
          >I think you both missed a case:
          >>
          > (1b) global x; del x # Remove x from global namespace
          > (1b) global x; x = 4 # Bind x to 4 in the global namespace
          >
          This is why you put 'current namespace' in quotes! But all three of
          us missed the case:
          I'd assumed you were just trying to say that the current namespace might
          be different things: locals or a class namespace. I would say that the
          global statement makes the assign/del refer to a non-current namespace.
          >
          (1-3000) What about nonlocal?
          What about nonlocal? You can't (in Python 2.x) assign or del a name from
          an enclosing scope if that's what you mean. If that isn't what you mean
          then you'll have to explain it to me in simpler terms.

          Comment

          • George Sakkis

            #6
            Re: The del statement

            On May 8, 2:58 am, Arnaud Delobelle <arno...@google mail.comwrote:
            George Sakkis wrote:
            One of the few Python constructs that feels less elegant than
            necessary to me is the del statement. For one thing, it is overloaded
            to mean three different things:
            (1) del x: Remove x from the current namespace
            (2) del x[i]: Equivalent to x.__delitem__(i )
            (3) del x.a: Equivalent to x.__delattr__(' a') (or delattr(x,'a'))
            >
            Note that the 'X = Y' construct has the corresponding three meanings:
            >
            (1) x = 4 # Bind x to 4 in the 'current namespace'
            (2) x[i] = 4 # equivalent to x.__setitem__(i , 4)
            (3) x.a = 4 # Equivalent to x.__setattr__(' a', 4)
            >
            What conclusion should we draw from that?
            I think you're trying to imply that it is consistent with setting a
            value (same with getting). I guess what bugs me about "del" is that
            it's a keyword and not some universally well-known punctuation. Do you
            you feel that Python misses a "pop" keyword and respective
            expressions ?

            (1) pop x: Remove x from the current namespace and return it.
            (2) pop x[i]: Instead of x.pop(i)
            (3) pop x.a: Equivalent to "_y=x.a; del x.a; return y"

            George

            Comment

            • Terry Reedy

              #7
              Re: The del statement


              "George Sakkis" <george.sakkis@ gmail.comwrote in message
              news:02860f2a-cd1d-4b1d-ad49-08b13032ba21@2g 2000hsn.googleg roups.com...
              | One of the few Python constructs that feels less elegant than
              | necessary to me is the del statement. For one thing, it is overloaded
              | to mean three different things:
              | (1) del x: Remove x from the current namespace
              | (2) del x[i]: Equivalent to x.__delitem__(i )
              | (3) del x.a: Equivalent to x.__delattr__(' a') (or delattr(x,'a'))

              Since I see del x.a as deleting a from the attribute namespace of x, I see
              this as the same meaning. A namespace is a specialized association (keys
              are identifier strings). A dict is more generalized (keys merely
              hashable). So ditto for del dic[key].

              The only different meaning is del somelist[i]. The implicit association
              between counts in range(n=len(som elist)) *is* broken, but unless i == n-1,
              items are 'shifted down' so that some other item become associated with i,
              and j's for i < j < n-1 get new associations and n-1 is left with none.
              One could imagine del somelist[i] as simple leaving a void in the list.
              (Which is not to say that that would be terribly useful.)

              tjr



              Comment

              • Michael Torrie

                #8
                Re: The del statement

                George Sakkis wrote:
                I think you're trying to imply that it is consistent with setting a
                value (same with getting). I guess what bugs me about "del" is that
                it's a keyword and not some universally well-known punctuation. Do you
                you feel that Python misses a "pop" keyword and respective
                expressions ?
                Typically the word "pop" has a different meaning than you describe.
                Most programmers think of pop in conjunction with push, for working with
                FIFOs. Normally pop would not be expected to take any arguments, or
                maybe an argument of a number describing how many items to pop off of a
                FIFO (stack). Thus I don't think a pop method would be the right way to
                go here.

                I don't feel python misses a pop keyword because pop is already used as
                methods of classes implementing stacks and FIFOs where appropriate.
                >
                (1) pop x: Remove x from the current namespace and return it.
                (2) pop x[i]: Instead of x.pop(i)
                (3) pop x.a: Equivalent to "_y=x.a; del x.a; return y"
                The confusion over del does stem from it's behavior, so I can see where
                you're coming from. del doesn't delete anything; it just removes a
                name. However pop would be just as confusing in my opinion, given that
                it's already associated with data structures.

                Comment

                Working...