使用变量作为具有预定义关键字的函数的关键字(Python)

时间:2016-09-16 20:04:11

标签: python datetime

我正在尝试创建一个简单的函数,允许用户输入将改变日期时间对象值的基本信息,我想找到一种方法,通过使用变量使其尽可能干净作为关键字。这可以通过不同的方式轻松完成,但我认为知道如何替换预设关键字会很有用。

datetime对象有一个.replace()方法,它将任意时间值作为关键字:

  

datetime.replace([year [,month [,day [,hour [,minute [,second [,microsecond [,tzinfo]]]]]]]])

但我希望允许用户指定多少时间(例如,2天; 4小时; 1个月)。

我正在尝试将任何上述关键字替换为“分钟”,无论用户输入是什么,存储在 time_type 变量中,但我得到“ TypeError:' time_type'是此函数的无效关键字参数“。

    start_time = datetime.datetime(2016, 09, 16, 15, 30)

    def change_time(integer, time_string):
        time_type = time_string.replace("s","")  # de-pluralizes input
        new_time = getattr(start_time, time_type) + integer
        print(start_time.replace(time_type=new_time))

    change_time(2, "days")

这应该打印新的start_time,即(2016,09,18,15,30),但我只是出错了。

3 个答案:

答案 0 :(得分:1)

您无法替换未编写的函数上的关键字参数。调用类似函数时:

f(a=b)

a的值不会作为参数发送给f。而是发送b的值,并将该值设置为a参数列表定义中的参数f's。如果f没有定义参数a(因为datetime.replace没有定义time_type参数),您将获得invalid keyword argument例外。

正如其他人所说,要将动态关键字参数传递给函数,请使用**kwargs表示法。

答案 1 :(得分:0)

Python允许您将数据存储在字典中,最后将它们解压缩为不同函数的关键字参数。

对于你想要做的事情,最好的方法就是使用kwargs。

replacement_info = {'day': 2, 'month': 9, ...}

new_time = start_time.replace(**replacement_info)

注意与你所做的不同。将time_type直接传递给replace会导致使用replace参数调用time_type,设置为2,这是未定义的(因为它不在接受的参数列表中)替换)

相反,你必须像**{time_type: 2}一样将它传递给replace函数,这样,replace将接收time_type的解释值,即day,作为输入。

所以你需要改变

print(start_time.replace(time_type=new_time))

print(start_time.replace(**{time_type:new_time})

答案 2 :(得分:0)

将您的最后一行更改为以下内容:

year = start_time.year
month = start_time.month
day = start_time.day
hour = start_time.hour
minute = start_time.minute
second = start_time.second
microsecond = start_time.microsecond
exec(time_type + '='+str(new_time))
print(start_time.replace(year, month, day, hour, minute, second, microsecond)