I have a custom function, and I am trying to do some error-trapping within a custom function with the idea of printing more user-friendly error messages as opposed to the bulky, somewhat intimidating-looking error blocks.
Here is my data and custom function:
import pandas as pd
data = {'col1':['a','b','c','d','e','f','g'],
'foo':[1,2,3,4,5,6,7],
'bar':[8,9,10,11,12,13,14],
'foobar':[15,16,17,18,19,20,21]}
df = pd.DataFrame(data)
df
#Function
def func(a, b, c, d):
"""
Parameters
---------------
a = String
name of col 2 in data frame
b = String
name of col 3 in data frame
c = String
name of col 4 in data frame
d = String
Name of last desired output column
Returns:
---------------
Input data frame with appended columns
Example:
---------------
func('foo', 'bar', 'foobar', lastcol)
"""
try:
df['new_col1'] = df[a] 44
df['new_col2'] = df[b] 88
df['new_col3'] = df[c] 133
if d is not None:
df[d] = df[a] df[b]
return df.head(5)
except NameError:
print('Input parameter(s) likely entered wrong.')
except TypeError as err:
print({}.format(err))
print('No input parameters can be blank.')
except KeyError:
print('KeyError: At least one input does not follow the input format. Type ?func to see examples.')
The KeyError works as expected, as misspelling one of the arguments func('fo', 'bar', 'foobar', 'lastcol')
produces the following message in plain text:
KeyError: At least one input does not follow the input format. Type ?func to see examples.
However, when leaving a parameter blank func(a = 'foo', b = 'bar', d = 'lastcol')
, the traditional error block is thrown even though I have included a TypeError
in my try-except
block.
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Input In [36], in <module>
----> 1 func(a = 'fo', b = 'bar', d = 'lastcol')
TypeError: func() missing 1 required positional argument: 'c'
How can I fix this so the entire error block is not thrown?
CodePudding user response:
The TypeError
is thrown before func
is actually called. A solution would be to wrap func
in a second function and inside it call func
:
def func(*args, **kwargs):
"""
Parameters
---------------
a = String
name of col 2 in data frame
b = String
name of col 3 in data frame
c = String
name of col 4 in data frame
d = String
Name of last desired output column
Returns:
---------------
Input data frame with appended columns
Example:
---------------
func('foo', 'bar', 'foobar', lastcol)
"""
try:
def _func(a, b, c, d):
"""
The real function.
"""
df['new_col1'] = df[a] 44
df['new_col2'] = df[b] 88
df['new_col3'] = df[c] 133
if d is not None:
df[d] = df[a] df[b]
return df.head(5)
_func(*args, **kwargs)
except NameError:
print('Input parameter(s) likely entered wrong.')
except TypeError as err:
print('{}'.format(err))
print('No input parameters can be blank.')
except KeyError:
print('KeyError: At least one input does not follow the input format. Type ?func to see examples.')
Testing:
>>> func(a = 'fo', b = 'bar', d = 'lastcol')
_func() missing 1 required positional argument: 'c'
No input parameters can be blank.