简体   繁体   English

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

[英]Use variables as keywords for functions with pre-defined keywords (Python)

I'm trying to create a simple function that allows a user to input basic information that will change the values of a datetime object, and I'd like to find a way to make it as clean as possible by using a variable as a keyword.我正在尝试创建一个简单的函数,该函数允许用户输入将更改 datetime 对象值的基本信息,并且我想找到一种方法,通过使用变量作为关键字来使其尽可能干净. This can easily be done a different way, but I figured it'd be useful to know how to replace pre-set keywords.这可以通过不同的方式轻松完成,但我认为了解如何替换预设关键字会很有用。

The datetime object has a .replace() method that takes any time value as a keyword: datetime 对象有一个 .replace() 方法,该方法将任何时间值作为关键字:

datetime.replace([year[, month[, day[, hour[, minute[, second[, microsecond[, tzinfo]]]]]]]]) datetime.replace([年[, 月[, 日[, 小时[, 分钟[, 秒[, 微秒[, tzinfo]]]]]]]])

But I want to allow the user to specify how much of which kind of time (eg, 2 days; 4 hours; 1 month).但我想让用户指定多少时间(例如,2 天;4 小时;1 个月)。

I'm trying to replace any of the above keywords up to "minute" with whatever the user inputs, which is stored in the time_type variable, but I get " TypeError: 'time_type' is an invalid keyword argument for this function ".我试图用存储在time_type变量中的任何用户输入替换上述任何关键字,直到“分钟”,但我得到“类型错误:'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")

This should print the new start_time, which is (2016, 09, 18, 15, 30), but I just get an error.这应该打印新的 start_time,即 (2016, 09, 18, 15, 30),但我只是收到一个错误。

Python allows you to store data in a dictionary and finally unpack them as keyword arguments to different functions. Python 允许您将数据存储在字典中,并最终将它们解包为不同函数的关键字参数。

For the thing that you want to do, best way to accomplish this is to use kwargs.对于你想做的事情,最好的方法是使用 kwargs。

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

new_time = start_time.replace(**replacement_info)

Note the difference with what you've done.注意与你所做的不同。 Passing time_type directly to replace , would result in replace being called with the time_type parameter, set to 2, which is undefined (since it's not in the list of accepted arguments for replace)time_type直接传递给replace ,将导致使用time_type参数调用replace ,该参数设置为 2,这是未定义的(因为它不在接受的替换参数列表中)

Instead you have to pass it like **{time_type: 2} to the replace function, this way, replace will receive the interpreted value for time_type, namely day, as the input.相反,您必须像**{time_type: 2}一样将它传递给替换函数,这样,替换将接收 time_type 的解释值,即日,作为输入。

So you need to change所以你需要改变

print(start_time.replace(time_type=new_time))

to

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

You cannot replace keyword arguments on a function you did not write.您不能替换不是您编写的函数的关键字参数。 When calling a function like:调用如下函数时:

f(a=b)

The value of a is not sent as an argument to f .的值a不发送作为参数f Instead, the value of b is sent and that value is set to the argument a in f's argument list definition.而是发送b的值,并将该值设置为f's参数列表定义中的参数a If f does not have an argument a defined (as datetime.replace does not have a time_type argument defined), you will get an invalid keyword argument exception.如果f没有定义参数a (因为datetime.replace没有定义time_type参数),你会得到一个invalid keyword argument异常。

As others have said, to pass dynamic keyword arguments to a function use the **kwargs notation.正如其他人所说,将动态关键字参数传递给函数使用**kwargs表示法。

Change your last line to something like this:将最后一行更改为如下所示:

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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM