In Python you can specify optional function arguments by providing a default value, for example:
def func(a, b, c=None):
if c is not None:
return f"a = {a}, b = {b}, c = {c}"
return f"a = {a}, b = {b}"
With PyXLL you can also specify default values in exactly the same way. For example, to expose the same function to Excel as a UDF using the @xl_func decorator you would do the following:
from pyxll import xl_func
@xl_func
def func(a, b, c=None):
if c is not None:
return f"a = {a}, b = {b}, c = {c}"
return f"a = {a}, b = {b}"
But what about the function signature? The @xl_func decorator takes an optional function signature that allows you to specify the argument types taken by the function. This is useful when your function expects a particular type, or makes use of on of PyXLL's type converters like the "dataframe" type that converts a 2d array of data from Excel into a Pandas DataFrame.
When providing a function signature for functions with optional arguments you specify the function signature in exactly the same way as when the argument is not optional. The type for the optional argument is supplied in the same way as usual. To continue the example above, this could be as follows:
from pyxll import xl_func
@xl_func("int a, float b, bool c: str")
def func(a, b, c=None):
if c is not None:
return f"a = {a}, b = {b}, c = {c}"
return f"a = {a}, b = {b}"
The fact that "c" is optional does not affect the signature passed to @xl_func as that only contains the type information.
If you do not want to specify types for all of the arguments you can use the @xl_arg and @xl_return decorators in addition to the @xl_func decorator. For example, if we only wanted to provide type information for a, b and the return value it would look as follows:
from pyxll import xl_func, xl_arg, xl_return
@xl_func
@xl_arg("a", "int")
@xl_arg("b", "float")
@xl_return("str")
def func(a, b, c=None):
if c is not None:
return f"a = {a}, b = {b}, c = {c}"
return f"a = {a}, b = {b}"