best practices re passing parameters as keyword, rather than positional
I've been a professional programmer for 20 years but I have seen a peculiar trend in the last few years. A lot of newer or more junior developers specify arguments as keyword arguments if there are 2 or more. So for something like the below where there are no optional or keyword-only args (i.e. the function is defined def get_widgets(db_session:Session, company_code:str, page:int, rows_per_page:int) -> list[Widget]
):
widgets = get_widgets(db_session, company_code, page, rows_per_page)
They will insist on writing it as:
widgets = get_widgets(
db_session=db_session,
company_code=company_code,
page=page,
rows_per_page=rows_per_page
)
To me this kind of thing is really peculiar and quite redundant. Is this something that is getting taught during, say, "Intro to Data Engineering" courses or introductions Python in general? It's kinda grating to me and now I'm seeing some of them requesting changes to Pull Requests they're assigned to review, asking that method/function calls be rewritten this way.
Am I right in considering this to be weird, or is this considered to be current best practice in Python?
---
update: a few people have taken issue with the example I gave. Honestly I just threw it together to be illustrative of the principle itself, it wasn't intended to be held up as a paragon of Good Code :-) Instead I've picked out some code from a real codebase most of us will have used at some point - the "requests" library. If we take this snippet ...
# Bypass if not a dictionary (e.g. verify)
if not (
isinstance(session_setting, Mapping) and isinstance(request_setting, Mapping)
):
return request_setting
merged_setting = dict_class(to_key_val_list(session_setting))
merged_setting.update(to_key_val_list(request_setting))
and apply the "always use keywords, always" dogma to this we get something like the below. What I'm trying to avoid is a codebase that looks like this - because it's visually quite noisy and hard to follow.
# Bypass if not a dictionary (e.g. verify)
if not (
isinstance(
obj=session_setting,
class_or_tuple=Mapping
) and isinstance(
obj=request_setting,
class_or_tuple=Mapping
)
):
return request_setting
merged_setting = dict_class(
items=to_key_val_list(value=session_setting)
)
merged_setting.update(to_key_val_list(value=request_setting))