Path: csiph.com!fu-berlin.de!uni-berlin.de!not-for-mail From: Chris Angelico Newsgroups: comp.lang.python Subject: Re: What is a function parameter =[] for? Date: Thu, 19 Nov 2015 12:59:18 +1100 Lines: 96 Message-ID: References: Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 X-Trace: news.uni-berlin.de PONJyKRx61tDfRm7I+xmdwVtbVmftOtI7YMmk0R6ubKg== Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.000 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'received:209.85.223': 0.03; 'args': 0.04; 'defaults': 0.05; 'none,': 0.05; '[],': 0.07; 'default.': 0.07; 'cc:addr:python-list': 0.09; 'argument,': 0.09; 'default:': 0.09; 'mutable': 0.09; 'objects.': 0.09; 'spelling': 0.09; 'syntax': 0.13; 'times,': 0.13; 'def': 0.13; 'argument': 0.15; 'result.': 0.15; 'thu,': 0.15; '"""if': 0.16; 'appends': 0.16; 'args[0]': 0.16; 'constructs': 0.16; 'distinction': 0.16; 'from:addr:rosuav': 0.16; 'from:name:chris angelico': 0.16; 'innocuous': 0.16; 'language)': 0.16; 'partly': 0.16; "peters'": 0.16; 'received:io': 0.16; 'received:psf.io': 0.16; 'wrote:': 0.16; 'mechanism': 0.18; 'specifies': 0.18; '2015': 0.20; 'cc:2**0': 0.20; 'cc:addr:python.org': 0.20; '(the': 0.22; 'arguments': 0.22; 'object.': 0.22; 'simpler': 0.22; 'sorry,': 0.22; 'appears': 0.23; 'bit': 0.23; 'dependent': 0.23; 'previously': 0.24; 'tim': 0.24; 'header:In-Reply-To:1': 0.24; 'example': 0.26; 'chris': 0.26; 'point.': 0.27; 'not.': 0.27; 'used,': 0.27; 'message-id:@mail.gmail.com': 0.27; 'function': 0.28; 'looks': 0.29; 'behind.': 0.29; 'objects': 0.29; 'print': 0.30; 'that.': 0.30; 'code': 0.30; 'certainly': 0.30; "i'd": 0.31; 'probably': 0.31; 'certain': 0.31; "can't": 0.32; 'common': 0.33; 'retain': 0.33; 'surprised': 0.33; 'values.': 0.33; 'that,': 0.34; 'list': 0.34; 'received:google.com': 0.35; 'could': 0.35; 'nov': 0.35; 'knowledge': 0.35; 'something': 0.35; 'but': 0.36; 'should': 0.36; 'received:209.85': 0.36; 'depends': 0.36; 'subject:?': 0.36; 'pm,': 0.36; 'subject:: ': 0.37; 'really': 0.37; 'two': 0.37; 'being': 0.37; 'agree': 0.37; 'expect': 0.37; 'say': 0.37; 'monitor': 0.38; 'received:209': 0.38; "didn't": 0.39; 'rather': 0.39; 'called': 0.40; 'some': 0.40; 'your': 0.60; 'entire': 0.61; 'default': 0.61; 'is.': 0.63; 'times': 0.63; 'due': 0.65; "they're": 0.66; 'situation': 0.67; 'guaranteed': 0.67; 'experts': 0.70; 'million': 0.74; 'obvious': 0.76; 'as:': 0.79; 'chrisa': 0.84; 'default?': 0.84; 'to:none': 0.91; 'glance': 0.91 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:cc :content-type; bh=Iw2fIO5agXkZ9ENHsA1i4ygz7+OzlUGEIiFG4D0xtDU=; b=y6ATmUz3uslUzKgPVNyeKj4QWgKDY0/3b1QzQ6PDvlAiLuDUWmbYXZ5uuV2aLhhWZR VLtUsJRsSFe6BQHV/eWjRL7vmLOCzT8NlwMVeeSsjlJQyN+Wq4nArQ0CWSLY6z9hOzPy 8GlWNXB3RFAhTHrs0WrU/nLUelnavnvA/UGoI1DbBFJ5m2VT3lMgiUfmSpBtkuH1K3E8 +cu3FppoCRLlRahAWTGWFDSvRl37+cg6k1wzOSWX+sOxFx8Rs2ZCo4FGKjtO9c4przIK sEnyXuKPoSLJhjcYl4EWKns8HjD2kz1b9/MhCK7L3M8lYBjVMkbnYKiqaOYJLkcjg+Q8 0bfw== X-Received: by 10.107.10.233 with SMTP id 102mr6047579iok.31.1447898359063; Wed, 18 Nov 2015 17:59:19 -0800 (PST) In-Reply-To: X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.20+ Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Xref: csiph.com comp.lang.python:99025 On Thu, Nov 19, 2015 at 12:41 PM, BartC wrote: > On 18/11/2015 23:22, Chris Angelico wrote: >> On the contrary, it is certain always to be that exact object. > > But, not the same value that appears as the default? Nope. Mutable objects are never guaranteed to retain the same values. That's kinda the point. > Sorry, I didn't understand any of that. Let's try a simpler example like the > OP's. There's this innocuous looking function that you are interested in > calling: > > def fn(a=[]): > # print ("Function fn called with",a) > | a.append(10) > | return a > > It appends a value to its argument and returns the result. > > It looks like at first like, if called with no argument, it will return > [10]. If you want to think of function defaults as being values, then yes. But they're not. They're objects. > But what it actually returns depends on the entire call history since the > program started executing, something you probably have no knowledge of and > no control over. So if fn has previously been called a million times with no > argument, then after this call: > > x=fn() > > x contains a list of a million tens, not one. I'd say most people would be > rather surprised by that. So if you don't want them to be surprised by that, don't use mutable default arguments and expect them to have specific values. > I suspect those same people (unless they are experts in the murky corners of > the language) would expect: > > x=fn() > > when fn specifies a default argument of [], to be the same as writing: > > x=fn([]) > > and not be dependent on fn's entire call history. Tell me, do you expect these to do the same thing? x = [] fn(x) fn(x) fn(x) # or fn([]) fn([]) fn([]) The distinction is exactly the same. If you can understand that the first one constructs a single object and uses it three times, then you should be able to understand that the function default is also constructed once and used every time. > Your solution of using: > > def fn(a=None): > > is not really satisfactory. Partly because it now utilities two mechanisms > for the default: first to get None, then some extra code to get []. But also > it's no longer obvious how the function works and what the default is. At > least, you can't tell from a glance at the start of the function that [] is > the default. This I do agree with. It's a bit clunky. It would be nice to be able to say: def fn(a=`[]`): """If a is not passed, it will be a new empty list""" and have it function the same as: def fn(*args): a = args[0] if args else [] but currently there's no mechanism for it. (The example spelling I gave is almost certainly not going to be used, due to the Tim Peters' Monitor Grit argument, but something could probably be found.) It's a sufficiently common situation that it would merit its own syntax. Want to write up a PEP? All you need is a syntax that people can get behind. ChrisA