Changing calling sequence

dn PythonList at DancesWithMice.info
Sat May 14 18:22:15 EDT 2022


On 12/05/2022 01.33, Michael F. Stemper wrote:
> I have a function that I use to retrieve daily data from a
> home-brew database. Its calling sequence is;
> 
> def TempsOneDay( year, month, date ):
> 
> After using it (and its friends) for a few years, I've come to
> realize that there are times where it would be advantageous to
> invoke it with a datetime.date as its single argument.
> 
> As far as I can tell, there are three ways for me to proceed:
> 1. Write a similar function that takes a single datetime.date
>    as its argument.
> 2. Rewrite the existing function so that it takes a single
>    argument, which can be either a tuple of (year,month,date)
>    or a datetime.date argument.
> 3. Rewrite the existing function so that its first argument
>    can be either an int (for year) or a datetime.date. The
>    existing month and date arguments would be optional, with
>    default=None. But, if the first argument is an int, and
>    either of month or date is None, an error would be raised.
> 
> The first would be the simplest. However, it is obviously WET
> rather than DRY.
> 
> The second isn't too bad, but a change like this would require that
> I find all places that the function is currently used and insert a
> pair of parentheses. Touching this much code is risky, as well
> as being a bunch of work. (Admittedly, I'd only do it once.)
> 
> The third is really klunky, but wouldn't need to touch anything
> besides this function.
> 
> What are others' thoughts? Which of the approaches above looks
> least undesirable (and why)? Can anybody see a fourth approach?


Reading the above, it seems that the options are limited to using
positional-arguments only. Because I keep tripping-over my long, grey,
beard; I'm reminded that relying upon my/human memory is, um, unreliable
(at least in my case). Accordingly, by the time a function's definition
reaches three parameters, I'll be converting it to use keyword-arguments
as a matter of policy. YMMV!

Remember: if keyword arguments are not used (ie existing/legacy code),
Python will still use positional logic.

Once the function's signature has been changed, we could then add
another keyword-parameter to cover the datetime option.


That said, a function which starts with a list of ifs-buts-and-maybes*
which are only there to ascertain which set of arguments have been
provided by the calling-routine; obscures the purpose/responsibility of
the function and decreases its readability (perhaps not by much, but
varying by situation).

Accordingly, if the function is actually a method, recommend following
@Stefan's approach, ie multiple-constructors. Although, this too can
result in lower readability.

Assuming it is a function, and that there are not many alternate
APIs/approaches (here we're discussing only two), I'd probably create a
wrapper-function which has the sole task of re-stating the datetime
whilst calling the existing three-parameter function. The readability
consideration here, is to make a good choice of (new) function-name!


* Python version >= 10? Consider using match-case construct keyed on
parameter-type
-- 
Regards,
=dn


More information about the Python-list mailing list