Skip to content

Instantly share code, notes, and snippets.

@nfirvine
Created June 15, 2016 18:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nfirvine/891970bf63211bba7a81e6816c3ff27f to your computer and use it in GitHub Desktop.
Save nfirvine/891970bf63211bba7a81e6816c3ff27f to your computer and use it in GitHub Desktop.
params=(): a new way to work around python's static default args
# coding:utf-8
# Which one of these approaches is best?
def append_bar(params=[]):
'''
Nope. This has a well-known problem: default args are created at definition,
not at call, so the globally-scoped `[]` value ends up getting reused
whenever we don't specify `params`:
>>> append_bar()
['bar']
>>> append_bar()
['bar', 'bar']
'''
params.append("bar")
return params
def append_bar2(params=None):
'''
The standard work around is this, and works as expected:
>>> append_bar2()
['bar']
>>> append_bar2()
['bar']
'''
params = params if params is not None else []
params.append("bar")
return params
def append_bar3(params=()):
'''
My new approach.
- 👍 clearer that params is expecting a seq
- 👍 concise
- 👎 extra copy
>>> append_bar3()
['bar']
>>> append_bar3()
['bar']
'''
params = list(params)
params.append("bar")
return params
def subst(params=()):
'''
And in the situation where we can guarantee we only read params:
- 👍 we can avoid munging it altogether
>>> subst(params=('bar', 'baz'))
'foo? bar;foo? baz;'
'''
return ('foo? %s;' * len(params)) % params
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment