I've poked around, but can nothing definitive on my particulars. I'm writing a function that takes one required and two optional parameters with default values, one of which needs to be a tuple:
def real_titlecase(lineString, delimiter = ' ', no_caps = do_not_cap):
I want the no_caps parameter tuple to default to do_not_cap if none is passed in. My problem is that I want to define do_not_cap within the function itself, and it contains about fifty items:
do_not_cap = ('A','a','AN','An','an','THE','The','the', . . . )
I have tried to define do_not_cap as the first item under the docstring at the top of the function def, but I get:
NameError: name 'do_not_cap' is not defined
when I call the function. I'm assuming that python encounters do_not_cap in the header and doesn't know it from a bale of hay because it hasn't been defined yet. For the sake of readability, I really don't want to define that tuple in the header, and I want it encapsulated within the function so it can properly function as a default.
So how can I do this?
Thanks!
The default value of a function needs to be defined at the time the function is being defined. You can't use a value that's only created when the function is run, that's much too late.
There are two possible solutions. One is to define the default value tuple outside of the function (just before it, perhaps):
do_not_cap = ('A', 'a', 'AN', 'An', 'an', 'THE', 'The', 'the', ...)
def real_titlecase(lineString, delimiter=' ', no_caps=do_not_cap):
...
If you want to discourage other uses of the tuple (e.g. you don't want it's name to be part of your API), you might want to use a "private" name prefixed by an underscore (e.g. _do_not_cap
instead of do_not_cap
).
The other option is to use a special sentinel value (such as None
) as the default value. At the top of the function, you can check for the sentinel, and substitute in the desired tuple if it's seen. You need to pick a sentinel that wouldn't be a valid user-provided argument. None
works fine for your example function, but in other cases you might need to use a different sentinel if None
could be a meaningful argument if passed in by a user.
def real_titlecase(lineString, delimiter=' ', no_caps=None):
if no_caps is None:
no_caps = ('A', 'a', 'AN', 'An', 'an', 'THE', 'The', 'the', ...)
...