Optional parameter object re-used when instantiating multiple objects

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

    Optional parameter object re-used when instantiating multiple objects

    Hello All,

    Why is python designed so that b and c (according to code below)
    actually share the same list object? It seems more natural to me that
    each object would be created with a new list object in the points
    variable.

    class Blob:
    def __init__(self, points=[]):
    self._points = points


    b = Blob()
    c = Blob()

    b._points.appen d(1)
    c._points.appen d(2)

    print b._points

    # this will show that b._points is the same object as c._points









  • Arnaud Delobelle

    #2
    Re: Optional parameter object re-used when instantiating multiple objects

    Rick Giuly <rgiuly.group@y ahoo.comwrites:
    Hello All,
    Hello,
    Why is python designed so that b and c (according to code below)
    actually share the same list object? It seems more natural to me that
    each object would be created with a new list object in the points
    variable.
    >
    class Blob:
    def __init__(self, points=[]):
    self._points = points
    >
    >
    b = Blob()
    c = Blob()
    >
    b._points.appen d(1)
    c._points.appen d(2)
    >
    print b._points
    >
    # this will show that b._points is the same object as c._points
    This is probably the MFAQ (Most FAQ)!

    Have a look in http://www.python.org/doc/faq/ (I can't point at the
    question as my internet pipes to the US are very rusty this morning)

    HTH

    --
    Arnaud

    Comment

    • Steven D'Aprano

      #3
      Re: Optional parameter object re-used when instantiating multipleobjects

      On Sat, 15 Nov 2008 01:40:04 -0800, Rick Giuly wrote:
      Hello All,
      >
      Why is python designed so that b and c (according to code below)
      actually share the same list object? It seems more natural to me that
      each object would be created with a new list object in the points
      variable.
      That's not natural *at all*. You're initialising the argument "points"
      with the same list every time. If you wanted it to have a different list
      each time, you should have said so. Don't blame the language for doing
      exactly what you told it to do.

      class Blob:
      def __init__(self, points=[]):
      self._points = points
      Let's analyze this. You create a method __init__. That function is
      created *once*. As part of the process of creating the function, the
      argument "points" is given the default value of an empty list. The
      creation of that empty list happens *once*, when the method is created.
      In the body of the function, you set the _points attribute to points.
      Naturally it is the same list object.

      Since the method is only created once, it is only natural that the
      default value is also only created once. If you want something to be
      created each time the function is called, you have to put it inside the
      body of the function:

      class Blob:
      def __init__(self, points=None):
      if points is None:
      points = []
      self._points = points

      Now you will have _points set to a unique empty list each time.



      This is no different from doing this:

      alist = []
      b1 = Blob(alist)
      b2 = Blob(alist)

      Would you be surprised that b1 and b2 share the same list? If yes, then
      you need to think about how Python really works, rather than how you
      imagine it works.



      --
      Steven

      Comment

      • Aaron Brady

        #4
        Re: Optional parameter object re-used when instantiating multipleobjects

        On Nov 15, 3:40 am, Rick Giuly <rgiuly.gr...@y ahoo.comwrote:
        Hello All,
        >
        Why is python designed so that b and c (according to code below)
        actually share the same list object? It seems more natural to me that
        each object would be created with a new list object in the points
        variable.
        >
        class Blob:
            def __init__(self, points=[]):
                self._points = points
        >
        b = Blob()
        c = Blob()
        >
        b._points.appen d(1)
        c._points.appen d(2)
        >
        print b._points
        >
        # this will show that b._points is the same object as c._points
        Hi Rick,

        I don't think Dennis or Steven read your post very well. You said
        'Why does Python do X?', and 'It seems natural to you to do not X'.
        Dennis and Steven both said, 'Python does X'.

        Steven did get around to suggesting an answer though. He said:
        If you want something to be
        created each time the function is called, you have to put it inside the
        body of the function:
        Taking this to be true, the answer to your question is, 'Because the
        object isn't created inside the body of the function,' or, 'Because
        the argument list is outside the body of the function'.

        From your post, it's hard to tell whether this 'duh'-type observation
        would point out the salient feature of the construct, or whether
        you're after something deeper.

        If you're asking, 'Why isn't the argument list considered to be inside
        the body?', then the answer is, it's pretty much arbitrary.
        Regardless of which one the author of Python chose, the other's
        workaround would be equally short, and neither one is obviously
        indicated by the syntax.

        And until someone sends you a link to Python's author's blog that
        gives the answer, 'To make creating static variables really easy',
        don't let them tell you so.

        Comment

        • Steven D'Aprano

          #5
          Re: Optional parameter object re-used when instantiating multipleobjects

          On Sat, 15 Nov 2008 21:29:22 -0800, Aaron Brady wrote:
          I don't think Dennis or Steven read your post very well.
          It's possible.
          You said 'Why
          does Python do X?', and 'It seems natural to you to do not X'. Dennis
          and Steven both said, 'Python does X'.
          I also disputed that it is natural to do not-X (runtime creation of
          default arguments), and explained why such an interpretation doesn't
          match with the way Python operates. I admit I didn't answer the "why"
          part.

          Steven did get around to suggesting an answer though. He said:
          >
          >If you want something to be
          >created each time the function is called, you have to put it inside the
          >body of the function:
          If you want to be pedantic, then my "answer" (which you seem to approve
          of) doesn't correspond to either of the original poster's questions. If
          you're going to be pedantic, then be pedantic all the way, and criticize
          me for answering a question that wasn't asked :-P

          Taking this to be true, the answer to your question is, 'Because the
          object isn't created inside the body of the function,' or, 'Because the
          argument list is outside the body of the function'.
          Actually, the correct answer to "Why?" would be "Because that's the
          decision Guido van Rossum made back in the early 1990s when he first
          started designing Python". That of course leads to the obvious question
          "Why did he make that decision?", and the answer to that is:

          * it leads to far more efficient performance when calling functions;

          E.g. if the default value is expensive to calculate, it is better to
          calculate it once, when the function is created, than every single time
          the function is called.

          Additionally, the effbot once mentioned in a similar thread that there
          are real performance benefits in the Python VM from binding the default
          value once only. I don't know the exact details of that, but I trust
          Fredrik knows what he's talking about.


          * it has less scope for surprise when calling functions.

          E.g. I would argue that most people would be surprised, and dismayed, if
          this code fails:

          x = 1
          def foo(a, b=x):
          return a+b

          del x
          print foo(2)

          From your post, it's hard to tell whether this 'duh'-type observation
          would point out the salient feature of the construct, or whether you're
          after something deeper.
          >
          If you're asking, 'Why isn't the argument list considered to be inside
          the body?', then the answer is, it's pretty much arbitrary.
          No, it is not an arbitrary choice. I've given practical reasons why the
          Python choice is better. If you want default argument to be created from
          scratch when the function is called, you can get it with little
          inconvenience, but the opposite isn't true. It is very difficult to get
          static default arguments given a hypothetical Python where default
          arguments are created from scratch. There's no simple, easy idiom that
          will work. The best I can come up with is a convention:

          # Please don't change this, or strange things will happen.
          _private = ResultOfExpensi veCalculation()

          def foo(a, b=_private):
          return a+b

          The above is still vulnerable to code accidentally over-writing _private
          with some other value, or deleting it, but at least we avoid the
          expensive calculation every time.

          Or possibly:

          def foo(a, b=foo._private) :
          return a+b

          foo._private = ResultOfExpensi veCalculation()

          which has obvious disadvantages with regard to shadowing, renaming,
          anonymous functions, and so forth.


          Regardless
          of which one the author of Python chose, the other's workaround would be
          equally short,
          Not true. One has an obvious workaround, the other only has a *partial*
          workaround.
          and neither one is obviously indicated by the syntax.
          I would disagree, but not enough to argue.


          --
          Steven

          Comment

          • Arnaud Delobelle

            #6
            Re: Optional parameter object re-used when instantiating multiple objects

            Steven D'Aprano <steve@REMOVE-THIS-cybersource.com .auwrites:
            On Sat, 15 Nov 2008 01:40:04 -0800, Rick Giuly wrote:
            >
            >Hello All,
            >>
            >Why is python designed so that b and c (according to code below)
            >actually share the same list object? It seems more natural to me that
            >each object would be created with a new list object in the points
            >variable.
            >
            That's not natural *at all*. You're initialising the argument "points"
            with the same list every time. If you wanted it to have a different list
            each time, you should have said so. Don't blame the language for doing
            exactly what you told it to do.
            Come on. The fact that this questions comes up so often (twice in 24h)
            is proof that this is a surprising behaviour. I do think it is the
            correct one but it is very natural to assume that when you write

            def foo(bar=[]):
            bar.append(6)
            ...

            you are describing what happens when you _call_ foo, i.e.:

            1. if bar is not provided, make it equal to []
            2. Append 6 to bar
            3. ...

            --
            Arnaud

            Comment

            • George Sakkis

              #7
              Re: Optional parameter object re-used when instantiating multipleobjects

              On Nov 16, 2:05 am, Arnaud Delobelle <arno...@google mail.comwrote:
              Steven D'Aprano <st...@REMOVE-THIS-cybersource.com .auwrites:
              On Sat, 15 Nov 2008 01:40:04 -0800, Rick Giuly wrote:
              >
              Hello All,
              >
              Why is python designed so that b and c (according to code below)
              actually share the same list object? It seems more natural to me that
              each object would be created with a new list object in the points
              variable.
              >
              That's not natural *at all*. You're initialising the argument "points"
              with the same list every time. If you wanted it to have a different list
              each time, you should have said so. Don't blame the language for doing
              exactly what you told it to do.
              >
              Come on.  The fact that this questions comes up so often (twice in 24h)
              is proof that this is a surprising behaviour.  I do think it is the
              correct one but it is very natural to assume that when you write
              >
                  def foo(bar=[]):
                       bar.append(6)
                       ...
              >
              you are describing what happens when you _call_ foo, i.e.:
              >
                  1. if bar is not provided, make it equal to []
                  2. Append 6 to bar
                  3. ...
              +1. Understanding and accepting the current behavior (mainly because
              of the extra performance penalty of evaluating the default expressions
              on every call would incur) is one thing, claiming that it is somehow
              natural is plain silly, as dozens of threads keep showing time and
              time again. For better or for worse the current semantics will
              probably stay forever but I wish Python grows at least a syntax to
              make the expected semantics easier to express, something like:

              def foo(bar=`[]`):
              bar.append(6)

              where `expr` would mean "evaluate the expression in the function
              body". Apart from the obvious usage for mutable objects, an added
              benefit would be to have default arguments that depend on previous
              arguments:

              def foo(x, y=`x*x`, z=`x+y`):
              return x+y+z

              as opposed to the more verbose and less obvious current hack:

              def foo(x, y=None, z=None):
              if y is None: y = x*x
              if z is None: z = x+y
              return x+y+z

              George

              Comment

              • Steven D'Aprano

                #8
                Re: Optional parameter object re-used when instantiating multipleobjects

                On Sun, 16 Nov 2008 07:05:51 +0000, Arnaud Delobelle wrote:
                Steven D'Aprano <steve@REMOVE-THIS-cybersource.com .auwrites:
                >
                >On Sat, 15 Nov 2008 01:40:04 -0800, Rick Giuly wrote:
                >>
                >>Hello All,
                >>>
                >>Why is python designed so that b and c (according to code below)
                >>actually share the same list object? It seems more natural to me that
                >>each object would be created with a new list object in the points
                >>variable.
                >>
                >That's not natural *at all*. You're initialising the argument "points"
                >with the same list every time. If you wanted it to have a different
                >list each time, you should have said so. Don't blame the language for
                >doing exactly what you told it to do.
                >
                Come on. The fact that this questions comes up so often (twice in 24h)
                is proof that this is a surprising behaviour.
                Of course it's surprising. People make an assumption based on other
                languages. But there is nothing "natural" about that assumption. It may
                be common, but that doesn't mean it's the only way to think about it.

                If you check the archives of this newsgroup, you will see that some time
                not very long ago I made the suggestion that perhaps Python should raise
                a warning when it creates a function with an obviously mutable default
                argument. In practice, that would mean checking for three special cases:
                [], {} and set(). So I'm sympathetic towards the surprise people feel,
                but I don't agree that it is natural. "Natural" is a thought-stopper.
                It's meant to imply that any other alternative is unnatural, crazy,
                stupid, perverted, or whatever other alternative to natural you prefer,
                therefore stop all disagreement.


                I do think it is the
                correct one but it is very natural to assume that when you write
                >
                def foo(bar=[]):
                bar.append(6)
                ...
                >
                you are describing what happens when you _call_ foo, i.e.:
                >
                1. if bar is not provided, make it equal to []
                2. Append 6 to bar
                3. ...

                Which is *exactly* what happens -- except of course once you append six
                to the list [], it now looks like [6].

                Why assume that "make it equal to []" implies a different list every
                time, rather than that it is a specific list that happens to start off as
                []? Why isn't it equally "natural" to assume that it's the same list each
                time, and it starts off as [] but need not stay that way?


                --
                Steven

                Comment

                • Steve Holden

                  #9
                  Re: Optional parameter object re-used when instantiating multipleobjects

                  George Sakkis wrote:
                  On Nov 16, 2:05 am, Arnaud Delobelle <arno...@google mail.comwrote:
                  >
                  >Steven D'Aprano <st...@REMOVE-THIS-cybersource.com .auwrites:
                  >>On Sat, 15 Nov 2008 01:40:04 -0800, Rick Giuly wrote:
                  >>>Hello All,
                  >>>Why is python designed so that b and c (according to code below)
                  >>>actually share the same list object? It seems more natural to me that
                  >>>each object would be created with a new list object in the points
                  >>>variable.
                  >>That's not natural *at all*. You're initialising the argument "points"
                  >>with the same list every time. If you wanted it to have a different list
                  >>each time, you should have said so. Don't blame the language for doing
                  >>exactly what you told it to do.
                  >Come on. The fact that this questions comes up so often (twice in 24h)
                  >is proof that this is a surprising behaviour. I do think it is the
                  >correct one but it is very natural to assume that when you write
                  >>
                  > def foo(bar=[]):
                  > bar.append(6)
                  > ...
                  >>
                  >you are describing what happens when you _call_ foo, i.e.:
                  >>
                  > 1. if bar is not provided, make it equal to []
                  > 2. Append 6 to bar
                  > 3. ...
                  >
                  +1. Understanding and accepting the current behavior (mainly because
                  of the extra performance penalty of evaluating the default expressions
                  on every call would incur) is one thing, claiming that it is somehow
                  natural is plain silly, as dozens of threads keep showing time and
                  time again. For better or for worse the current semantics will
                  probably stay forever but I wish Python grows at least a syntax to
                  make the expected semantics easier to express, something like:
                  >
                  def foo(bar=`[]`):
                  bar.append(6)
                  >
                  where `expr` would mean "evaluate the expression in the function
                  body". Apart from the obvious usage for mutable objects, an added
                  benefit would be to have default arguments that depend on previous
                  arguments:
                  >
                  Would you also retain the context surrounding the function declaration
                  so it's obvious how it will be evaluated, or would you limit the default
                  values to expressions with no bound variables?
                  def foo(x, y=`x*x`, z=`x+y`):
                  return x+y+z
                  >
                  as opposed to the more verbose and less obvious current hack:
                  >
                  def foo(x, y=None, z=None):
                  if y is None: y = x*x
                  if z is None: z = x+y
                  return x+y+z
                  >
                  "Less obvious" is entirely in the mind of the reader. However I can see
                  far more justification for the behavior Python currently exhibits than
                  the semantic time-bomb you are proposing.

                  regards
                  Steve
                  --
                  Steve Holden +1 571 484 6266 +1 800 494 3119
                  Holden Web LLC http://www.holdenweb.com/

                  Comment

                  • Steve Holden

                    #10
                    Re: Optional parameter object re-used when instantiating multipleobjects

                    George Sakkis wrote:
                    On Nov 16, 2:05 am, Arnaud Delobelle <arno...@google mail.comwrote:
                    >
                    >Steven D'Aprano <st...@REMOVE-THIS-cybersource.com .auwrites:
                    >>On Sat, 15 Nov 2008 01:40:04 -0800, Rick Giuly wrote:
                    >>>Hello All,
                    >>>Why is python designed so that b and c (according to code below)
                    >>>actually share the same list object? It seems more natural to me that
                    >>>each object would be created with a new list object in the points
                    >>>variable.
                    >>That's not natural *at all*. You're initialising the argument "points"
                    >>with the same list every time. If you wanted it to have a different list
                    >>each time, you should have said so. Don't blame the language for doing
                    >>exactly what you told it to do.
                    >Come on. The fact that this questions comes up so often (twice in 24h)
                    >is proof that this is a surprising behaviour. I do think it is the
                    >correct one but it is very natural to assume that when you write
                    >>
                    > def foo(bar=[]):
                    > bar.append(6)
                    > ...
                    >>
                    >you are describing what happens when you _call_ foo, i.e.:
                    >>
                    > 1. if bar is not provided, make it equal to []
                    > 2. Append 6 to bar
                    > 3. ...
                    >
                    +1. Understanding and accepting the current behavior (mainly because
                    of the extra performance penalty of evaluating the default expressions
                    on every call would incur) is one thing, claiming that it is somehow
                    natural is plain silly, as dozens of threads keep showing time and
                    time again. For better or for worse the current semantics will
                    probably stay forever but I wish Python grows at least a syntax to
                    make the expected semantics easier to express, something like:
                    >
                    def foo(bar=`[]`):
                    bar.append(6)
                    >
                    where `expr` would mean "evaluate the expression in the function
                    body". Apart from the obvious usage for mutable objects, an added
                    benefit would be to have default arguments that depend on previous
                    arguments:
                    >
                    Would you also retain the context surrounding the function declaration
                    so it's obvious how it will be evaluated, or would you limit the default
                    values to expressions with no bound variables?
                    def foo(x, y=`x*x`, z=`x+y`):
                    return x+y+z
                    >
                    as opposed to the more verbose and less obvious current hack:
                    >
                    def foo(x, y=None, z=None):
                    if y is None: y = x*x
                    if z is None: z = x+y
                    return x+y+z
                    >
                    "Less obvious" is entirely in the mind of the reader. However I can see
                    far more justification for the behavior Python currently exhibits than
                    the semantic time-bomb you are proposing.

                    regards
                    Steve
                    --
                    Steve Holden +1 571 484 6266 +1 800 494 3119
                    Holden Web LLC http://www.holdenweb.com/

                    Comment

                    • Steve Holden

                      #11
                      Re: Optional parameter object re-used when instantiating multipleobjects

                      Dennis Lee Bieber wrote:
                      On Sat, 15 Nov 2008 01:40:04 -0800 (PST), Rick Giuly
                      <rgiuly.group@y ahoo.comdeclaim ed the following in comp.lang.pytho n:
                      >
                      >Why is python designed so that b and c (according to code below)
                      >actually share the same list object? It seems more natural to me that
                      >each object would be created with a new list object in the points
                      >variable.
                      >>
                      This is a FAQ... default arguments are evaluation only ONCE, during
                      the "compilatio n" of the function.
                      >
                      >class Blob:
                      > def __init__(self, points=[]):
                      > self._points = points
                      >>
                      The preferred/recommended form is to use (very explicit, one test,
                      one "assignment ")
                      >
                      def __init__(self, points=None):
                      if points:
                      self._points = points
                      else:
                      self._points = []
                      >
                      or (shorter; one test, potentially two "assignment s")
                      >
                      def __init__(self, points=None):
                      if not points: points = []
                      self._points = points
                      >
                      I hesitate to beat the thoroughly obvious to death with a stick, but
                      this is a *very* bad way to make the test. If you are using None as a
                      sentinel to indicate that no argument was provided to the call then the
                      correct test is

                      if points is None:
                      points = []

                      The code shown fails to distinguish between passing an empty list and
                      not passing an argument at all.

                      regards
                      Steve

                      --
                      Steve Holden +1 571 484 6266 +1 800 494 3119
                      Holden Web LLC http://www.holdenweb.com/

                      Comment

                      • George Sakkis

                        #12
                        Re: Optional parameter object re-used when instantiating multipleobjects

                        On Nov 16, 8:28 am, Steve Holden <st...@holdenwe b.comwrote:
                        >
                        +1. Understanding and accepting the current behavior (mainly because
                        of the extra performance penalty of evaluating the default expressions
                        on every call would incur) is one thing, claiming that it is somehow
                        natural is plain silly, as dozens of threads keep showing time and
                        time again. For better or for worse the current semantics will
                        probably stay forever but I wish Python grows at least a syntax to
                        make the expected semantics easier to express, something like:
                        >
                        def foo(bar=`[]`):
                        bar.append(6)
                        >
                        where `expr` would mean "evaluate the expression in the function
                        body". Apart from the obvious usage for mutable objects, an added
                        benefit would be to have default arguments that depend on previous
                        arguments:
                        >
                        Would you also retain the context surrounding the function declaration
                        so it's obvious how it will be evaluated, or would you limit the default
                        values to expressions with no bound variables?
                        No, all expressions would be allowed, and the semantics would be
                        identical to evaluating them in the function body; not context would
                        be necessary.
                        def foo(x, y=`x*x`, z=`x+y`):
                        return x+y+z
                        >
                        as opposed to the more verbose and less obvious current hack:
                        >
                        def foo(x, y=None, z=None):
                        if y is None: y = x*x
                        if z is None: z = x+y
                        return x+y+z
                        >
                        "Less obvious" is entirely in the mind of the reader.
                        Without documentation or peeking into the function body, a None
                        default conveys little or no information, so I don't think it's just
                        in the mind of the reader. Do you find the following less obvious than
                        the current workaround ?

                        from datetime import date
                        from timedelta import timedelta

                        def make_reservatio n(customer,
                        checkin=`date.t oday()`,
                        checkout=`check in+timedelta(da ys=3)`):
                        ...

                        However I can see
                        far more justification for the behavior Python currently exhibits than
                        the semantic time-bomb you are proposing.
                        I didn't propose replacing the current behavior (that would cause way
                        too much breakage), only adding a new syntax which is now invalid, so
                        one would have to specify it explicitly.

                        George

                        Comment

                        • Chris Rebert

                          #13
                          Re: Optional parameter object re-used when instantiating multipleobjects

                          On Sun, Nov 16, 2008 at 11:02 AM, George Sakkis <george.sakkis@ gmail.comwrote:
                          On Nov 16, 8:28 am, Steve Holden <st...@holdenwe b.comwrote:
                          >>
                          +1. Understanding and accepting the current behavior (mainly because
                          of the extra performance penalty of evaluating the default expressions
                          on every call would incur) is one thing, claiming that it is somehow
                          natural is plain silly, as dozens of threads keep showing time and
                          time again. For better or for worse the current semantics will
                          probably stay forever but I wish Python grows at least a syntax to
                          make the expected semantics easier to express, something like:
                          >>
                          def foo(bar=`[]`):
                          bar.append(6)
                          >>
                          where `expr` would mean "evaluate the expression in the function
                          body". Apart from the obvious usage for mutable objects, an added
                          benefit would be to have default arguments that depend on previous
                          arguments:
                          >>
                          >Would you also retain the context surrounding the function declaration
                          >so it's obvious how it will be evaluated, or would you limit the default
                          >values to expressions with no bound variables?
                          >
                          No, all expressions would be allowed, and the semantics would be
                          identical to evaluating them in the function body; not context would
                          be necessary.
                          >
                          def foo(x, y=`x*x`, z=`x+y`):
                          return x+y+z
                          >>
                          as opposed to the more verbose and less obvious current hack:
                          >>
                          def foo(x, y=None, z=None):
                          if y is None: y = x*x
                          if z is None: z = x+y
                          return x+y+z
                          >>
                          >"Less obvious" is entirely in the mind of the reader.
                          >
                          Without documentation or peeking into the function body, a None
                          default conveys little or no information, so I don't think it's just
                          in the mind of the reader. Do you find the following less obvious than
                          the current workaround ?
                          >
                          from datetime import date
                          from timedelta import timedelta
                          >
                          def make_reservatio n(customer,
                          checkin=`date.t oday()`,
                          checkout=`check in+timedelta(da ys=3)`):
                          ...
                          >
                          >
                          >However I can see
                          >far more justification for the behavior Python currently exhibits than
                          >the semantic time-bomb you are proposing.
                          >
                          I didn't propose replacing the current behavior (that would cause way
                          too much breakage), only adding a new syntax which is now invalid, so
                          one would have to specify it explicitly.
                          Minor FYI, but Guido has proscribed backticks ever being used in
                          Python again. See http://www.python.org/dev/peps/pep-3099/

                          Cheers,
                          Chris
                          --
                          Follow the path of the Iguana...

                          Comment

                          • George Sakkis

                            #14
                            Re: Optional parameter object re-used when instantiating multipleobjects

                            On Nov 16, 2:30 pm, "Chris Rebert" <c...@rebertia. comwrote:
                            On Sun, Nov 16, 2008 at 11:02 AM, George Sakkis <george.sak...@ gmail.com>wrote :
                            On Nov 16, 8:28 am, Steve Holden <st...@holdenwe b.comwrote:
                            >
                            "Less obvious" is entirely in the mind of the reader.
                            >
                            Without documentation or peeking into the function body, a None
                            default conveys little or no information, so I don't think it's just
                            in the mind of the reader. Do you find the following less obvious than
                            the current workaround ?
                            >
                            from datetime import date
                            from timedelta import timedelta
                            >
                            def make_reservatio n(customer,
                                                checkin=`date.t oday()`,
                                                checkout=`check in+timedelta(da ys=3)`):
                              ...
                            >
                            However I can see
                            far more justification for the behavior Python currently exhibits than
                            the semantic time-bomb you are proposing.
                            >
                            I didn't propose replacing the current behavior (that would cause way
                            too much breakage), only adding a new syntax which is now invalid, so
                            one would have to specify it explicitly.
                            >
                            Minor FYI, but Guido has proscribed backticks ever being used in
                            Python again. Seehttp://www.python.org/dev/peps/pep-3099/
                            I know, just used it for the sake of the example; the actual syntax is
                            much less of an issue in this case than the functionality.

                            George

                            Comment

                            • Aaron Brady

                              #15
                              Re: Optional parameter object re-used when instantiating multipleobjects

                              On Nov 16, 4:05 am, Steven D'Aprano <st...@REMOVE-THIS-
                              cybersource.com .auwrote:
                              On Sun, 16 Nov 2008 07:05:51 +0000, Arnaud Delobelle wrote:
                              Steven D'Aprano <st...@REMOVE-THIS-cybersource.com .auwrites:
                              >
                              On Sat, 15 Nov 2008 01:40:04 -0800, Rick Giuly wrote:
                              >
                              >Hello All,
                              >
                              >Why is python designed so that b and c (according to code below)
                              >actually share the same list object? It seems more natural to me that
                              >each object would be created with a new list object in the points
                              >variable.
                              >
                              That's not natural *at all*. You're initialising the argument "points"
                              with the same list every time. If you wanted it to have a different
                              list each time, you should have said so. Don't blame the language for
                              doing exactly what you told it to do.
                              >
                              Come on.  The fact that this questions comes up so often (twice in 24h)
                              is proof that this is a surprising behaviour.
                              >
                              Of course it's surprising. People make an assumption based on other
                              languages. But there is nothing "natural" about that assumption. It may
                              be common, but that doesn't mean it's the only way to think about it.
                              My point is that neither one is more natural than the other. I think
                              that more than one person has shirked the burden of proof in making
                              claims about naturality, as well as overstepped the bounds of what a
                              conclusion about naturality entails. In other words, "Prove it. So
                              what?"

                              def f( a= [] ):
                              a.append( 0 )
                              return a

                              a= f()
                              b= f()
                              c= f( [] )

                              a== b!= c, because '[]' is not the default value, because '[] is not
                              []'.

                              If I run 'a= []' ten times in a loop, '[]' is executed ten times. If
                              I call 'f' ten times, '[]' is only executed once. You do have a case
                              that the function is defined once, but executed ten times.
                              Why assume that "make it equal to []" implies a different list every
                              time, rather than that it is a specific list that happens to start off as
                              []? Why isn't it equally "natural" to assume that it's the same list each
                              time, and it starts off as [] but need not stay that way?
                              In other words, what does 'natural' mean? Either provide an analytic
                              definition (strict necessary and sufficient conditions), or some
                              paradigm cases. 'Natural' in the sense that killing is natural? Are
                              there any such senses? Is natural always best? Is natural always
                              obvious?

                              Oddly, http://dictionary.reference.com/browse/natural has 38
                              definitions in the longest entry.

                              Comment

                              Working...