Bug in python!? persistent value of an optional parameter in function!

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • C Barr Leigh

    Bug in python!? persistent value of an optional parameter in function!

    Help! Have I found a serious bug?
    This seems like highly undesired behaviour to me. From the program
    below, I get output:

    call1: ['sdf']
    call2: ['Set within test for call2']
    call3: ['Set within test for call2']

    instead of what I should get,

    call1: ['sdf']
    call2: ['Set within test for call2']
    call3: ['Set within test for call3']

    I'm using Python 2.4.4c1 (#2, Oct 11 2006, 21:51:02). The code is
    below.


    #!/usr/bin/python

    def testPersistence (anarg,twooptio n=[]):
    #print anarg
    if not twooption:
    twooption.appen d('Set within test for '+anarg)
    print anarg +': '+str(twooption )

    testPersistence ('call1',twoopt ion=['sdf']);
    testPersistence ('call2');
    testPersistence ('call3');

  • Paul Rubin

    #2
    Re: Bug in python!? persistent value of an optional parameter in function!

    "C Barr Leigh" <cpblPublic@gma il.comwrites:
    Help! Have I found a serious bug?
    This seems like highly undesired behaviour to me. From the program
    below, I get output:
    It is intentional, not a bug, see the docs. Whether it's desirable is
    a different question.

    Comment

    • Gabriel Genellina

      #3
      Re: Bug in python!? persistent value of an optional parameter infunction!

      En Wed, 07 Mar 2007 23:39:21 -0300, C Barr Leigh <cpblPublic@gma il.com>
      escribió:
      Help! Have I found a serious bug?
      Not at all! This is by design.
      def testPersistence (anarg,twooptio n=[]):
      #print anarg
      if not twooption:
      twooption.appen d('Set within test for '+anarg)
      See


      --
      Gabriel Genellina

      Comment

      • John Nagle

        #4
        Re: Bug in python!? persistent value of an optional parameter infunction!

        Paul Rubin wrote:
        "C Barr Leigh" <cpblPublic@gma il.comwrites:
        >
        >>Help! Have I found a serious bug?
        >>This seems like highly undesired behaviour to me. From the program
        >>below, I get output:
        >
        >
        It is intentional, not a bug, see the docs. Whether it's desirable is
        a different question.
        True. It would make sense to disallow mutable values as
        initial values for optional arguments. The present behavior
        is silly.

        John Nagle

        Comment

        • Paul Rubin

          #5
          Re: Bug in python!? persistent value of an optional parameter in function!

          John Nagle <nagle@animats. comwrites:
          True. It would make sense to disallow mutable values as
          initial values for optional arguments. The present behavior is silly.
          That would be the worst of both worlds. The main alternative to the
          present behavior is re-computing the default value every time the
          function is entered.

          Comment

          • George Sakkis

            #6
            Re: Bug in python!? persistent value of an optional parameter in function!

            On Mar 7, 10:14 pm, John Nagle <n...@animats.c omwrote:
            Paul Rubin wrote:
            "C Barr Leigh" <cpblPub...@gma il.comwrites:
            >
            >Help! Have I found a serious bug?
            >This seems like highly undesired behaviour to me. From the program
            >below, I get output:
            >
            It is intentional, not a bug, see the docs. Whether it's desirable is
            a different question.
            >
            True. It would make sense to disallow mutable values as
            initial values for optional arguments. The present behavior
            is silly.
            1. If you'd given it a little more thought than it took you to write
            this, you would perhaps realize that it is in general impossible to
            determine automatically whether an arbitrary object is mutable or
            not.

            2. Even if you could determine it, it would be overly restrictive to
            disallow all mutable values from defaults. The fact that an object is
            mutable doesn't mean that the function will try to mutate it:

            def paintWall(ind, colormap={1:'re d', 2:'blue', 5:'green'}):
            print "Let's paint the wall %s" % colormap[ind]


            George

            Comment

            • George Sakkis

              #7
              Re: Bug in python!? persistent value of an optional parameter in function!

              On Mar 7, 10:24 pm, Paul Rubin <http://phr...@NOSPAM.i nvalidwrote:
              John Nagle <n...@animats.c omwrites:
              True. It would make sense to disallow mutable values as
              initial values for optional arguments. The present behavior is silly.
              >
              That would be the worst of both worlds. The main alternative to the
              present behavior is re-computing the default value every time the
              function is entered.
              One can do this is today's Python if he's so inclined, albeit with a
              more verbose syntax: http://aspn.activestate.com/ASPN/Coo.../Recipe/502206

              George

              Comment

              • Steven D'Aprano

                #8
                Re: Bug in python!? persistent value of an optional parameter in function!

                On Thu, 08 Mar 2007 03:14:53 +0000, John Nagle wrote:
                Paul Rubin wrote:
                >"C Barr Leigh" <cpblPublic@gma il.comwrites:
                >>
                >>>Help! Have I found a serious bug?
                >>>This seems like highly undesired behaviour to me. From the program
                >>>below, I get output:
                >>
                >>
                >It is intentional, not a bug, see the docs. Whether it's desirable is
                >a different question.
                >
                True. It would make sense to disallow mutable values as
                initial values for optional arguments. The present behavior
                is silly.
                It's just *different*, not silly.

                It's also quite useful in some circumstances, e.g. cheap caching without
                using a global variable.

                def factorial(n, _cache={}):
                try:
                return _cache[n]
                except KeyError:
                # fall back to slow calculation
                if n <= 1:
                result = 1
                else:
                result = factorial(n-1)*n
                _cache[n] = result
                return result

                There are other ways of implementing caches, but this is quick and easy
                and works well for many functions.


                --
                Steven D'Aprano

                Comment

                • Paul Rubin

                  #9
                  Re: Bug in python!? persistent value of an optional parameter in function!

                  Steven D'Aprano <steve@REMOVEME .cybersource.co m.auwrites:
                  def factorial(n, _cache={}):
                  try:
                  return _cache[n]
                  except KeyError:
                  There are other ways of implementing caches, but this is quick and easy
                  and works well for many functions.
                  I like this better (examples are untested):

                  def factorial(n):
                  try:
                  return factorial.cache[n]
                  except KeyError: pass
                  ...
                  factorial.cache = {}

                  you could even use a decorator:

                  def memoize(f): # memoize a 1-arg function
                  f.cache = {}
                  def g(f,x):
                  if x in f.cache: return f.cache[x]
                  return f.cache.setdefa ult(x, f(x))
                  return functools.parti al(g,f)
                  ...

                  @memoize
                  def factorial(n):
                  return 1 if n==0 else n*factorial(n-1)

                  Comment

                  • C Barr Leigh

                    #10
                    Re: Bug in python!? persistent value of an optional parameter in function!

                    Oh, oops! Of course... :) A great and sensible feature if you're
                    expecting it.
                    Thanks very much, everyone, for the links and discussion!

                    Chris

                    Comment

                    • Bjoern Schliessmann

                      #11
                      Re: Bug in python!? persistent value of an optional parameter in function!

                      John Nagle wrote:
                      True. It would make sense to disallow mutable values as
                      initial values for optional arguments. The present behavior
                      is silly.
                      Why? You're free to only use immutables.

                      Regards,


                      Björn

                      --
                      BOFH excuse #42:

                      spaghetti cable cause packet failure

                      Comment

                      • Bruno Desthuilliers

                        #12
                        Re: Bug in python!? persistent value of an optional parameter infunction!

                        C Barr Leigh a écrit :
                        Help! Have I found a serious bug?
                        No. This is a FAQ. Default arguments of functions are evaled only once -
                        when the def statement is eval'd and the function object constructed.
                        This seems like highly undesired behaviour to me.
                        Possibly, but this is unlikely to change in a near future, so you'd
                        better get used to it. If you want mutable objects as default values for
                        functions, the idiom is:

                        def some_func(defau lt=None):
                        if default is None:
                        default = []
                        # code here

                        HTH

                        Comment

                        • Ayaz Ahmed Khan

                          #13
                          Re: Bug in python!? persistent value of an optional parameter in function!

                          "Gabriel Genellina" typed:Thanks for the link, Gabriel. I didn't know about this.

                          --
                          Ayaz Ahmed Khan

                          Falling in love makes smoking pot all day look like the ultimate in
                          restraint.
                          -- Dave Sim, author of "Cerebus".

                          Comment

                          Working...