Why the “mutable default argument fix” syntax is so ugly, asks python newbie

前端 未结 8 651
悲&欢浪女
悲&欢浪女 2020-11-30 09:00

Now following my series of \"python newbie questions\" and based on another question.

Prerogative

Go to http://python.net/~goodger/projects/pyco

8条回答
  •  渐次进展
    2020-11-30 09:28

    I've edited this answer to include thoughts from the many comments posted in the question.

    The example you give is flawed. It modifies the list that you pass it as a side effect. If that's how you intended the function to work, it wouldn't make sense to have a default argument. Nor would it make sense to return the updated list. Without a default argument, the problem goes away.

    If the intent was to return a new list, you need to make a copy of the input list. Python prefers that things be explicit, so it's up to you to make the copy.

    def better_append(new_item, a_list=[]): 
        new_list = list(a_list)
        new_list.append(new_item) 
        return new_list 
    

    For something a little different, you can make a generator that can take a list or a generator as input:

    def generator_append(new_item, a_list=[]):
        for x in a_list:
            yield x
        yield new_item
    

    I think you're under the misconception that Python treats mutable and immutable default arguments differently; that's simply not true. Rather, the immutability of the argument makes you change your code in a subtle way to do the right thing automatically. Take your example and make it apply to a string rather than a list:

    def string_append(new_item, a_string=''):
        a_string = a_string + new_item
        return a_string
    

    This code doesn't change the passed string - it can't, because strings are immutable. It creates a new string, and assigns a_string to that new string. The default argument can be used over and over again because it doesn't change, you made a copy of it at the start.

提交回复
热议问题