How to make a new default argument list every time [duplicate]

你说的曾经没有我的故事 提交于 2019-12-13 10:29:07

问题


I have the following setup:

def returnList(arg=["abc"]):
    return arg

list1 = returnList()
list2 = returnList()

list2.append("def")

print("list1: " + " ".join(list1) + "\n" + "list2: " + " ".join(list2) + "\n")

print(id(list1))
print(id(list2))

Output:

list1: abc def
list2: abc def

140218365917160
140218365917160

I can see that arg=["abc"] returns copy of the same default list rather than create a new one every time.

I have tried doing

def returnList(arg=["abc"][:]):

and

def returnList(arg=list(["abc"])):

Is it possible to get a new list, or must I copy the list inside the method everytime I want to some kind of default value?


回答1:


The nicest pattern I've seen is just

def returnList(arg=None):
    if arg is None: arg = ["abc"]
    ...

The only potential problem is if you expect None to be a valid input here which in which case you'll have to use a different sentinel value.

The problem with your approach is that args default argument is evaluated once. It doesn't matter what copying operators you do because it's simply evaluated than stored with the function. It's not re-evaluated during each function call.

Update:

I didn't want nneonneo's comment to be missed, using a fresh object as a sentinel would work nicely.

default = object()
def f(x = default):
    if x is default:
        ...



回答2:


What you want is what you state yourself: You want a new copy of the value each time. Simply calling a function does not do anything automatically, so there is no way to have this accomplished just by a syntactic trick. But you can use a decorator to do what you want:

import copy

def keepDefaults(f):
  defaults = f.func_defaults
  def wrapped(*args, **kwargs):
    f.func_defaults = copy.deepcopy(defaults)
    return f(*args, **kwargs)
  return wrapped

@keepDefaults
def f(a=[1]):
  return a

f()[0].append(2)
print f()  # will print "[1]" instead of "[1, 2]"


来源:https://stackoverflow.com/questions/17991492/how-to-make-a-new-default-argument-list-every-time

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!