Search code examples
pythonfunctionvariablesparameter-passingkeyword-argument

Using Variable as Keyword Argument for Function


I have the following piece of code:

quantity_of_units = int(funding_time_left.split[0])
unit_of_measurement = funding_time_left.split()[1]
now = datetime.datetime.now()
if unit_of_measurement == 'days':
    end = (now + timedelta(days=quantity_of_units)).strftime('%Y-%m-%d')
elif unit_of_measurement == 'hours':
    end = (now + timedelta(hours=quantity_of_units)).strftime('%Y-%m-%d')
else: # unit_of_measure == 'minutes'
    end = (now + timedelta(minutes=quantity_of_units)).strftime('%Y-%m-%d')
funding.append([aeles.get_attribute('href'), end])

I was wondering if it is possible to use a variable (unit_of_measurement) as the keyword argument (days, hours, minutes)?

If it is indeed possible, I could scrap the if elif else block altogether and turn it all into a single line. Below is what I'm hoping to do.

quantity_of_units = int(funding_time_left.split[0])
unit_of_measurement = funding_time_left.split()[1]
now = datetime.datetime.now()
end = (now + timedelta(unit_of_measurement=quantity_of_units)).strftime('%Y-%m-%d')
funding.append([aeles.get_attribute('href'), end])

Solution

  • You can, by using ** to unpack a dict in the arguments, which sets them to be keyword arguments.

    timedelta(**{unit_of_measurement: quantity_of_units})
    

    The reason why it works is because that unpacks to:

    timedelta(<unit_of_measurement>=quantity_of_units)
    

    Where <unit_of_measurement> is minutes, seconds, days...


    So you can replace your if... elif... else... statements with:

    end = (now + timedelta(**{unit_of_measurement: quantity_of_units})).strftime('%Y-%m-%d')