Is there a way in Python to pass optional parameters to a function while calling it and in the function definition have some code based on "only if the optional parameter is passed"
5 Answers
The Python 2 documentation, 7.6. Function definitions gives you a couple of ways to detect whether a caller supplied an optional parameter.
First, you can use special formal parameter syntax *
. If the function definition has a formal parameter preceded by a single *
, then Python populates that parameter with any positional parameters that aren't matched by preceding formal parameters (as a tuple). If the function definition has a formal parameter preceded by **
, then Python populates that parameter with any keyword parameters that aren't matched by preceding formal parameters (as a dict). The function's implementation can check the contents of these parameters for any "optional parameters" of the sort you want.
For instance, here's a function opt_fun
which takes two positional parameters x1
and x2
, and looks for another keyword parameter named "optional".
>>> def opt_fun(x1, x2, *positional_parameters, **keyword_parameters):
... if ('optional' in keyword_parameters):
... print 'optional parameter found, it is ', keyword_parameters['optional']
... else:
... print 'no optional parameter, sorry'
...
>>> opt_fun(1, 2)
no optional parameter, sorry
>>> opt_fun(1,2, optional="yes")
optional parameter found, it is yes
>>> opt_fun(1,2, another="yes")
no optional parameter, sorry
Second, you can supply a default parameter value of some value like None
which a caller would never use. If the parameter has this default value, you know the caller did not specify the parameter. If the parameter has a non-default value, you know it came from the caller.

- 10,960
- 3
- 45
- 74
-
7`positional_parameters` is a tuple, and `keyword_parameters` a dictionary. – Cees Timmerman Jan 08 '16 at 16:31
-
How does python distinguish `formal parameters preceded by * ` (what is this called?) from a `keyword parameter`? As I understood it, keyword parameters are specified using the `=` operator in the function call (so `opt_fun(1,2, optional="yes")` provides a keyword argument "yes" for a function that anticipates, but doesn't necessarily require, the parameter `option`). – Minh Tran Feb 05 '18 at 18:59
-
On the other hand, I understood `formal parameters preceded by * ` as simply "the caller-provided arguments that doesn't correspond to positional arguments that goes before any keyword arguments". For example, in `opt_fun(1,2, "blah", 3.14, mykey="yes", myyear="2018")`, `"blah"` and `3.14` are `forma arguments preceded by *` because it's in between the two positional arguments and the argument that uses the `=` sign. The resulting tuple `positional_parameter` would be the duple: `("blah", 3.14)`. Is this correct? – Minh Tran Feb 05 '18 at 19:02
-
@MinhTran, questions in comments are not the best way to get an answer in Stack Overflow. It's far better to click the big blue "Ask Question" button, and write your request as a "Question" which others can "Answer". But to help you, a) note I wrote "`parameter`" not "`parameters`" for "`preceded by *`". The language allows for only one `*identifier` in the parameter list. b) read https://docs.python.org/2/reference/compound_stmts.html#function-definitions, c) read https://docs.python.org/2/reference/expressions.html#calls . Sorry, running out of characters permitted in this comment. – Jim DeLaHunt Feb 06 '18 at 19:19
def my_func(mandatory_arg, optional_arg=100):
print(mandatory_arg, optional_arg)
http://docs.python.org/2/tutorial/controlflow.html#default-argument-values
I find this more readable than using **kwargs
.
To determine if an argument was passed at all, I use a custom utility object as the default value:
MISSING = object()
def func(arg=MISSING):
if arg is MISSING:
...

- 57,116
- 41
- 173
- 227
-
-Thanks,is there a way to specify the default value of this parameter as another variable in the code? – user1795998 Dec 24 '12 at 07:00
-
yes. `default_value=100; def my_func(mandatory_argument, optional_argument_with_default_value=default_value): ...` – warvariuc Dec 24 '12 at 07:21
-
This appears to show how to use optional parameters, but not how to test if one is passed,which is what the OP is asking. – Mawg says reinstate Monica Mar 07 '16 at 10:38
-
4In most cases this is the simpler and more straightforwad solution than Jim's. If you set the default value to None then you can check if the parameter was passed or not. The only case where Jim's solution is better is if it's important to distinguish between passing None as the argument and not passing an argument at all. – Arnon Axelrod Sep 05 '16 at 12:28
def op(a=4,b=6):
add = a+b
print add
i)op() [o/p: will be (4+6)=10]
ii)op(99) [o/p: will be (99+6)=105]
iii)op(1,1) [o/p: will be (1+1)=2]
Note:
If none or one parameter is passed the default passed parameter will be considered for the function.

- 864
- 10
- 22
-
1Is there a way to pass only the second parameter (b) and not the first one (a)? – Djidiouf Jul 03 '17 at 02:09
-
5
If you want give some default value to a parameter assign value in (). like (x =10). But important is first should compulsory argument then default value.
eg.
(y, x =10)
but
(x=10, y) is wrong

- 112
- 6
-
Thanks,is there a way to specify the default value of this parameter as another variable in the code? – user1795998 Dec 24 '12 at 06:58
-
Yes you can use something called `*arg` `**karg` as function arguments. search on google. – sumit Dec 24 '12 at 07:20
-
This appears to show how to use optional parameters, but not how to test if one is passed,which is what the OP is asking. – Mawg says reinstate Monica Mar 07 '16 at 10:38
You can specify a default value for the optional argument with something that would never passed to the function and check it with the is
operator:
class _NO_DEFAULT:
def __repr__(self):return "<no default>"
_NO_DEFAULT = _NO_DEFAULT()
def func(optional= _NO_DEFAULT):
if optional is _NO_DEFAULT:
print("the optional argument was not passed")
else:
print("the optional argument was:",optional)
then as long as you do not do func(_NO_DEFAULT)
you can be accurately detect whether the argument was passed or not, and unlike the accepted answer you don't have to worry about side effects of ** notation:
# these two work the same as using **
func()
func(optional=1)
# the optional argument can be positional or keyword unlike using **
func(1)
#this correctly raises an error where as it would need to be explicitly checked when using **
func(invalid_arg=7)

- 20,699
- 5
- 35
- 59
-
-
2 extra lines to give better introspection is worth it. With this if you run `help(func)` you get a clearer idea how the argument is interpreted if not passed explicitly. – Tadhg McDonald-Jensen Nov 08 '18 at 18:50