Difference between 'is' and '=='

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

    #16
    Re: Difference between 'is' and '=='

    In article <48q9pfFlc8q0U1 @uni-berlin.de>,
    "Diez B. Roggisch" <deets@nospam.w eb.de> wrote:
    ....[color=blue]
    > So - your conclusion is basically right: use is on (complex) objects, not on
    > numbers and strings and other built-ins. The exception from the rule is
    > None - that should only exist once, so
    >
    > foo is not None
    >
    > is considered better style than foo == None.[/color]

    But even better style is just `foo' or `not foo'. Or not,
    depending on what you're thinking.

    The key point between `is' and `==' has already been made -
    - use `is' to compare identity
    - use `==' to compare value

    It's that simple, and it's hard to add to this without
    potentially layering some confusion on it. While Python's
    implementation makes the use of identity with small numbers
    a slightly more complicated issue, there isn't a lot of
    practical difference. To take a common case that has already
    been mentioned here, if I define some constant symbolic values
    as small integers, as long as I take care that their values
    are distinct, I can reasonably use identity and ignore this
    technical weakness. I can assume that no one is going to
    supply randomly selected integers in this context. Meanwhile,
    the use of identity clarifies the intent.

    Depending, of course, on what the intent may be, which brings
    us to None, and a point about values in Python that was brought
    to a fairly brilliant light some years back by someone we don't
    hear from often here any more, unfortunately.

    - use `is' to compare identity
    - use `==' to compare value
    - use neither to test for `somethingness'

    I'm not going to try to elucidate the theory of something and
    nothing in Python, but suffice it to say that there are places
    where it may be better to write

    if not expr:

    than

    if expr is None:

    or worse yet,

    if expr == False:

    That's what I think, anyway.

    Donn Cave, donn@u.washingt on.edu

    Comment

    • Terry Reedy

      #17
      Re: Difference between 'is' and '=='


      "Clemens Hepper" <ethrandil@gmx. net> wrote in message
      news:e08qgg$nt$ 1@news2.open-news-network.org...
      [color=blue]
      > It's strange: python seem to cache constants from 0 to 99:[/color]

      The Python specification allows but does not require such behind-the-scenes
      implementation optimization hacks. As released, CPython 2.4 caches -5 to
      99, I believe. In 2.5, the upper limit was increased to 256. The limits
      are in a pair of #define statements in the int object source file. Anyone
      who compiles from source can adjust as desired (though the corresponding
      test will fail unless also adjusted ;-).

      I think the visibility of this implementation detail from Python code is an
      example of a leaky abstraction. For more, see
      There’s a key piece of magic in the engineering of the Internet which you rely on every single day. It happens in the TCP protocol, one of the fundamental building blocks of the Internet. TCP…


      Terry Jan Reedy



      Comment

      • Erik Max Francis

        #18
        Re: Difference between 'is' and '=='

        Terry Reedy wrote:
        [color=blue]
        > The Python specification allows but does not require such behind-the-scenes
        > implementation optimization hacks. As released, CPython 2.4 caches -5 to
        > 99, I believe. In 2.5, the upper limit was increased to 256. The limits
        > are in a pair of #define statements in the int object source file. Anyone
        > who compiles from source can adjust as desired (though the corresponding
        > test will fail unless also adjusted ;-).
        >
        > I think the visibility of this implementation detail from Python code is an
        > example of a leaky abstraction. For more, see
        > http://www.joelonsoftware.com/articl...tractions.html[/color]

        I don't see that as quite the same thing. That you can fiddle around
        with the `is` operator to investigate how small integers are cached
        doesn't really reveal any profound underlying abstraction, except that
        maybe all Python entities are true objects and that integers are
        immutable, which are things hopefully everyone was already aware of.

        If you're trying to test integer equality, you should be using the `==`
        operator, not the `is` operator, so what you find out about how things
        are caching is really irrelevant.

        --
        Erik Max Francis && max@alcyone.com && http://www.alcyone.com/max/
        San Jose, CA, USA && 37 20 N 121 53 W && AIM erikmaxfrancis
        And covenants, without the sword, are but words and of no strength to
        secure a man at all. -- Thomas Hobbes, 1588-1679

        Comment

        • Rene Pijlman

          #19
          Re: Difference between 'is' and '=='

          Terry Reedy:[color=blue]
          >The Python specification allows but does not require such behind-the-scenes
          >implementati on optimization hacks. As released, CPython 2.4 caches -5 to
          >99, I believe. In 2.5, the upper limit was increased to 256. The limits
          >are in a pair of #define statements in the int object source file. Anyone
          >who compiles from source can adjust as desired (though the corresponding
          >test will fail unless also adjusted ;-).
          >
          >I think the visibility of this implementation detail from Python code is an
          >example of a leaky abstraction. For more, see
          >http://www.joelonsoftware.com/articl...tractions.html[/color]

          Joel has his abstractions wrong. TCP doesn't guarantee reliable delivery,
          unlike IP it delivers reliably or it tells you it cannot. SQL perormance
          doesn't break abstraction, since performance isn't part of SQL. You _can_
          drive as fast when it's raining.

          Now, about identity and equality. As you know, identity implies equality,
          but equality doesn't imply identity. You seem to assume that when identity
          is not implied, it should be undetectable. But why?

          Here's A, there's B, they may or may not be identical, they may or may not
          be equal.

          What are you suggesting?

          1. If A and B are of comparable types, and A equals B, we should not be
          allowed to evaluate "A is B".

          2. If A and B are of comparable types, and A equals B, A should be B.

          3. If A and B are of comparable types, and A equals B, A should not be B.

          4. If A and B are of comparable types, and A equals B, "A is B" should not
          evaluate to a boolean value.

          5. When A and B are of comparable types, we should not be allowed to
          evaluate "A == B" :-)

          --
          René Pijlman

          Comment

          • Dan Sommers

            #20
            Re: Difference between 'is' and '=='

            On Mon, 27 Mar 2006 11:08:36 -0300,
            Felipe Almeida Lessa <felipe.lessa@g mail.com> wrote:
            [color=blue]
            > Em Seg, 2006-03-27 às 08:23 -0500, Dan Sommers escreveu:[color=green]
            >> On Mon, 27 Mar 2006 14:52:46 +0200,
            >> Joel Hedlund <joel.hedlund@g mail.com> wrote:
            >>[color=darkred]
            >> > ... According to PEP8 (python programming style guidelines) you should
            >> > use 'is' when comparing to singletons like None. I take this to also
            >> > include constants and such ...[/color]
            >>
            >> This does *not* also mean constants and such:
            >>
            >> Python 2.4.2 (#1, Feb 22 2006, 08:02:53)
            >> [GCC 4.0.1 (Apple Computer, Inc. build 5247)] on darwin
            >> Type "help", "copyright" , "credits" or "license" for more information.[color=darkred]
            >> >>> a = 123456789
            >> >>> a == 123456789[/color]
            >> True[color=darkred]
            >> >>> a is 123456789[/color]
            >> False[color=darkred]
            >> >>>[/color][/color][/color]
            [color=blue]
            > Not those kind of constants, but this one:[/color]
            [color=blue]
            > Python 2.4.2 (#2, Nov 20 2005, 17:04:48)
            > [GCC 4.0.3 20051111 (prerelease) (Debian 4.0.2-4)] on linux2
            > Type "help", "copyright" , "credits" or "license" for more information.[color=green][color=darkred]
            >>>> CONST = 123456789
            >>>> a = CONST
            >>>> a == CONST[/color][/color]
            > True[color=green][color=darkred]
            >>>> a is CONST[/color][/color]
            > True[color=green][color=darkred]
            >>>>[/color][/color][/color]

            That's a little misleading, and goes back to the questions of "what is
            assignment in Python?" and "What does it mean for an object to be
            mutable?"

            The line "a = CONST" simply gives CONST a new name. After that, "a is
            CONST" will be True no matter what CONST was. Under some circumstances,
            I can even change CONST, and "a is CONST" will *still* be True.
            [color=blue][color=green][color=darkred]
            >>> CONST = range(22)
            >>> a = CONST
            >>> a[/color][/color][/color]
            [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21][color=blue][color=green][color=darkred]
            >>> a is CONST[/color][/color][/color]
            True[color=blue][color=green][color=darkred]
            >>> CONST[12] = 'foo'
            >>> a is CONST[/color][/color][/color]
            True[color=blue][color=green][color=darkred]
            >>>[/color][/color][/color]

            Right off the top of my head, I can't think of a way to make "a = b; a
            is b" return False.

            Regards,
            Dan

            --
            Dan Sommers
            <http://www.tombstoneze ro.net/dan/>
            "I wish people would die in alphabetical order." -- My wife, the genealogist

            Comment

            • Felipe Almeida Lessa

              #21
              Re: Difference between 'is' and '=='

              Em Seg, 2006-03-27 às 21:05 -0500, Dan Sommers escreveu:[color=blue]
              > Right off the top of my head, I can't think of a way to make "a = b; a
              > is b" return False.[/color]

              Sorry for being so --quiet. I will try to be more --verbose.

              I can think of two types of constants:
              1) Those defined in the language, like True, None, 0 and the like.
              2) Those defined on your code.

              You said type 1 can be used with "is", you're right:[color=blue][color=green][color=darkred]
              >>> a = 100
              >>> a is 100[/color][/color][/color]
              False

              I said type 2 can (maybe "should"?) be used with "is", and AFAICT I'm
              right as well:[color=blue][color=green][color=darkred]
              >>> b = a
              >>> b is a[/color][/color][/color]
              True

              That said, you can do thinks like:[color=blue][color=green][color=darkred]
              >>> import socket
              >>> a = socket.AF_UNIX
              >>> a is socket.AF_UNIX[/color][/color][/color]
              True

              That kind of constants can be used with "is". But if don't want to be
              prone to errors as I do, use "is" only when you really know for sure
              that you're dealing with singletons.

              HTH,

              --
              Felipe.

              Comment

              • alex23

                #22
                Re: Difference between 'is' and '=='

                Felipe Almeida Lessa wrote:[color=blue]
                > I said [constants defined in your code] can (maybe "should"?) be used with "is", and
                > AFAICT I'm right as well:[color=green][color=darkred]
                > >>> b = a
                > >>> b is a[/color][/color]
                > True[/color]

                You should _never_ use 'is' to check for equivalence of value. Yes, due
                to the implementation of CPython the behaviour you quote above does
                occur, but it doesn't mean quite what you seem to think it does.

                Try this:
                [color=blue][color=green][color=darkred]
                >>> UPPERLIMIT = 100
                >>> i = 0
                >>> while not (i is UPPERLIMIT):
                >>> i+=1
                >>> print i[/color][/color][/color]

                Comparing a changing variable to a pre-defined constant seems a lot
                more general a use case than sequential binding & comparison...an d as
                this should show, 'is' does _not_ catch these cases.

                - alex23

                Comment

                • Antoon Pardon

                  #23
                  Re: Difference between 'is' and '=='

                  Op 2006-03-27, Donn Cave schreef <donn@u.washing ton.edu>:[color=blue]
                  > In article <48q9pfFlc8q0U1 @uni-berlin.de>,
                  > "Diez B. Roggisch" <deets@nospam.w eb.de> wrote:
                  > ...[color=green]
                  >> So - your conclusion is basically right: use is on (complex) objects, not on
                  >> numbers and strings and other built-ins. The exception from the rule is
                  >> None - that should only exist once, so
                  >>
                  >> foo is not None
                  >>
                  >> is considered better style than foo == None.[/color]
                  >
                  > But even better style is just `foo' or `not foo'. Or not,
                  > depending on what you're thinking.[/color]

                  No it is not. When you need None to be treated special,
                  that doesn't imply you want to treat zero numbers or empty
                  sequences as special too.

                  --
                  Antoon Pardon

                  Comment

                  • Felipe Almeida Lessa

                    #24
                    Re: Difference between 'is' and '=='

                    Em Seg, 2006-03-27 às 23:02 -0800, alex23 escreveu:[color=blue]
                    > Felipe Almeida Lessa wrote:[color=green]
                    > > I said [constants defined in your code] can (maybe "should"?) be used with "is", and
                    > > AFAICT I'm right as well:[color=darkred]
                    > > >>> b = a
                    > > >>> b is a[/color]
                    > > True[/color]
                    >
                    > You should _never_ use 'is' to check for equivalence of value. Yes, due
                    > to the implementation of CPython the behaviour you quote above does
                    > occur, but it doesn't mean quite what you seem to think it does.[/color]

                    /me not checking for value. I'm checking for identity. Suppose "a" is a
                    constant. I want to check if "b" is the same constant.
                    [color=blue]
                    > Try this:
                    >[color=green][color=darkred]
                    > >>> UPPERLIMIT = 100
                    > >>> i = 0
                    > >>> while not (i is UPPERLIMIT):
                    > >>> i+=1
                    > >>> print i[/color][/color]
                    >
                    > Comparing a changing variable to a pre-defined constant seems a lot
                    > more general a use case than sequential binding & comparison...an d as
                    > this should show, 'is' does _not_ catch these cases.[/color]

                    That's *another* kind of constant. I gave you the example of
                    socket.AF_UNIX, the kind of constant I'm talking about. Are you going to
                    sequentially create numbers until you find it? Of couse not.

                    The problem with Python (and other languages like Jave) is that we don't
                    have a type like an enum (yet) so we have to define constants in our
                    code. By doing an "is" instead of a "==" you *can* catch some errors.
                    For example, a very dummy function (picked MSG_EOR as its value is
                    greater than 99):

                    ---
                    from socket import MSG_EOR, MSG_WAITALL

                    def test(type):
                    if type is MSG_EOR:
                    print "This *is* MSG_EOR"
                    elif type == MSG_EOR:
                    print "This maybe be MSG_EOR"
                    else:
                    print "*Not MSG_EOR"
                    ---

                    Now testing it:
                    [color=blue][color=green][color=darkred]
                    >>> test(MSG_EOR)[/color][/color][/color]
                    This *is* MSG_EOR

                    Fine, but:
                    [color=blue][color=green][color=darkred]
                    >>> print MSG_EOR[/color][/color][/color]
                    128[color=blue][color=green][color=darkred]
                    >>> test(128)[/color][/color][/color]
                    This maybe be MSG_EOR

                    This is a mistake. Here I knew 128 == MSG_EOR, but what if that was a
                    coincidence of some other function I created? I would *never* catch that
                    bug as the function that tests for MSG_EOR expects any integer. By
                    testing with "is" you test for *that* integer, the one defined on your
                    module and that shouldn't go out of it anyway.

                    Of course using an enum should make all said here obsolete.

                    --
                    Felipe.

                    Comment

                    • Joel Hedlund

                      #25
                      Re: Difference between 'is' and '=='

                      > This does *not* also mean constants and such:
                      <snip>[color=blue][color=green][color=darkred]
                      > >>> a = 123456789
                      > >>> a == 123456789[/color][/color]
                      > True[color=green][color=darkred]
                      > >>> a is 123456789[/color][/color]
                      > False[color=green][color=darkred]
                      > >>>[/color][/color][/color]

                      I didn't mean that kind of constant. I meant named constants with defined
                      meaning, as in the example that I cooked up in my post. More examples: os.R_OK,
                      or more complex ones like mymodule.DEFAUL T_CONNECTION_CL ASS.

                      Sorry for causing unneccessary confusion.

                      Cheers!
                      /Joel Hedlund

                      Comment

                      • Joel Hedlund

                        #26
                        Re: Difference between 'is' and '=='

                        >>You should _never_ use 'is' to check for equivalence of value. Yes, due[color=blue][color=green]
                        >>to the implementation of CPython the behaviour you quote above does
                        >>occur, but it doesn't mean quite what you seem to think it does.[/color]
                        >
                        >
                        > /me not checking for value. I'm checking for identity. Suppose "a" is a
                        > constant. I want to check if "b" is the same constant.[/color]

                        /me too. That's what my example was all about. I was using identity to a known
                        CONSTANT (in caps as per python naming conventions :-) to sidestep costly value
                        equality computations.
                        [color=blue]
                        > By doing an "is" instead of a "==" you *can* catch some errors.
                        > <snip>
                        > By
                        > testing with "is" you test for *that* integer, the one defined on your
                        > module and that shouldn't go out of it anyway.[/color]

                        I totally agree with you on this point. Anything that helps guarding against
                        "stealthed" errors is a good thing by my standards.

                        Cheers!
                        /Joel Hedlund

                        Comment

                        • Joel Hedlund

                          #27
                          Re: Difference between 'is' and '=='

                          >>Not those kind of constants, but this one:[color=blue]
                          >
                          >[color=green]
                          >>Python 2.4.2 (#2, Nov 20 2005, 17:04:48)
                          >>[GCC 4.0.3 20051111 (prerelease) (Debian 4.0.2-4)] on linux2
                          >>Type "help", "copyright" , "credits" or "license" for more information.
                          >>[color=darkred]
                          >>>>>CONST = 123456789
                          >>>>>a = CONST
                          >>>>>a == CONST[/color]
                          >>
                          >>True
                          >>[color=darkred]
                          >>>>>a is CONST[/color]
                          >>
                          >>True
                          >>[/color]
                          >
                          > That's a little misleading, and goes back to the questions of "what is
                          > assignment in Python?" and "What does it mean for an object to be
                          > mutable?"
                          >
                          > The line "a = CONST" simply gives CONST a new name. After that, "a is
                          > CONST" will be True no matter what CONST was. Under some circumstances,
                          > I can even change CONST, and "a is CONST" will *still* be True.[/color]

                          Anyone who thinks it's a good idea to change a CONST that's not in a module
                          that they have full control over must really know what they're doing or suffer
                          the consequences. Most often, the consequences will be nasty bugs.

                          Cheers!
                          /Joel Hedlund

                          Comment

                          • Joel Hedlund

                            #28
                            Re: Difference between 'is' and '=='

                            > a is None[color=blue]
                            >
                            > is quicker than
                            >
                            > a == None[/color]

                            I think it's not such a good idea to focus on speed gains here, since they
                            really are marginal (max 2 seconds total after 10000000 comparisons):
                            [color=blue][color=green][color=darkred]
                            >>> import timeit
                            >>> print timeit.Timer("a == None", "a = 1").timeit(int( 1e7))[/color][/color][/color]
                            4.19580316544[color=blue][color=green][color=darkred]
                            >>> print timeit.Timer("a == None", "a = None").timeit(i nt(1e7))[/color][/color][/color]
                            3.20231699944[color=blue][color=green][color=darkred]
                            >>> print timeit.Timer("a is None", "a = 1").timeit(int( 1e7))[/color][/color][/color]
                            2.37486410141[color=blue][color=green][color=darkred]
                            >>> print timeit.Timer("a is None", "a = None").timeit(i nt(1e7))[/color][/color][/color]
                            2.48372101784

                            Your observation is certainly correct, but I think it's better applied to more
                            complex comparisons (say for example comparisons between gigantic objects or
                            objects where value equality determination require a lot of nontrivial
                            computations). That's where any real speed gains can be found. PEP8 tells me
                            it's better style to write "a is None" and that's good enough for me. Otherwise
                            I try to stay away from speed microoptimisati ons as much as possible since it
                            generally results in less readable code, which in turn often results in an
                            overall speed loss because code maintenance will be harder.

                            Cheers!
                            /Joel Hedlund

                            Comment

                            • Tim Churches

                              #29
                              Link to Daily Python-URL from www.python.org?

                              Am I correct in thinking that there is no longer any link from anywhere
                              on the Python Web site at http;//www.python.org to the Daily Python-URL
                              at http://www.pythonware.com/daily/ ? There is no sign of it on the
                              Community page, nor any reference to it at http://planet.python.org/

                              I'm sure there was a link to it last time I looked.

                              Tim C




                              Comment

                              • Peter Otten

                                #30
                                Re: Link to Daily Python-URL from www.python.org?

                                Tim Churches wrote:
                                [color=blue]
                                > Am I correct in thinking that there is no longer any link from anywhere
                                > on the Python Web site at http;//www.python.org to the Daily Python-URL
                                > at http://www.pythonware.com/daily/ ? There is no sign of it on the
                                > Community page, nor any reference to it at http://planet.python.org/[/color]

                                See http://www.python.org/links/
                                All links provided on that page would benefit from a short description.

                                Peter

                                Comment

                                Working...