简体   繁体   English

Python函数定义,函数作为可选参数

[英]Python function definition with function as optional argument

I would like to have a function as an optional argument of another function in python but it is not clear for me how I can do that. 我想在python中有一个函数作为另一个函数的可选参数,但我不清楚如何才能做到这一点。

For example I define the following function: 例如,我定义了以下函数:

import os, time, datetime

def f(t=datetime.datetime.now()):
    return t.timetuple()

I have placed t=datetime.datetime.now() in order for the argument to be optional so to be able to call f() with no arguments. 我已经放置t=datetime.datetime.now()以使参数是可选的,以便能够在没有参数的情况下调用f()

Now whenever in time I execute f() I get the same datetime A (which is wrong according to what I expect), but whenever in time I execute f(datetime.datetime.now()) I get different datetimes (which is correct as expected). 现在每当我执行f()我得到相同的日期时间A(根据我的预期是错误的),但每当我执行f(datetime.datetime.now())我得到不同的日期时间(这是正确的)如预期的那样)。

For example 例如

>>> f()
time.struct_time(tm_year=2015, tm_mon=6, tm_mday=20, tm_hour=15, tm_min=36, tm_sec=2, tm_wday=5, tm_yday=171, tm_isdst=-1)
>>> f()
time.struct_time(tm_year=2015, tm_mon=6, tm_mday=20, tm_hour=15, tm_min=36, tm_sec=2, tm_wday=5, tm_yday=171, tm_isdst=-1)
>>> f(datetime.datetime.now())
time.struct_time(tm_year=2015, tm_mon=6, tm_mday=20, tm_hour=15, tm_min=37, tm_sec=1, tm_wday=5, tm_yday=171, tm_isdst=-1)
>>> f()
time.struct_time(tm_year=2015, tm_mon=6, tm_mday=20, tm_hour=15, tm_min=36, tm_sec=2, tm_wday=5, tm_yday=171, tm_isdst=-1)

So why the fourth call returns me back to min 36 and sec 2 while the call was made before that? 那么为什么第四次通话会让我回到最低点36和秒2,同时在此之前进行通话? Why the first two calls give the same exact time even if I let plenty of time between them? 为什么前两个调用给出相同的确切时间,即使我在它们之间有足够的时间?

As mentioned by flask, the default value is evaluated when the function is parsed, so it will be set to one time. 正如flask所述,在解析函数时会计算默认值,因此它将被设置为一次。

The typical solution to this, is to not have the default a mutable value. 对此的典型解决方案是不具有默认的可变值。 You can do the followings: 您可以执行以下操作:

def f(t=None):
    if not t:
        t = datetime.datetime.now()
    return t.timetuple()

BTW, for the readers' benefit, you should try to use meaningful method and variable names. 顺便说一下,为了读者的利益,你应该尝试使用有意义的方法和变量名。

You can prevent the function from being evaluated by assigning the function when loading it into your second function. 您可以通过在将函数加载到第二个函数时分配函数来阻止评估函数。

import datetime

def f(t = datetime.datetime.now()):
    return t.timetuple()

def main(ff=f):
    print ff
    print ff()

>>> main()
<function f at 0x10a4e6938>
time.struct_time(tm_year=2015, tm_mon=6, tm_mday=20, tm_hour=15, tm_min=39, tm_sec=28, tm_wday=5, tm_yday=171, tm_isdst=-1)

edit: function is always evaluated in parameter. 编辑:函数始终在参数中计算。 Solution: decouple it's assignment from the parameter 解决方案:将其分配与参数分离

def f(t="now"):
    if t=="now":
        return datetime.datetime.now().timetuple()
    else:
        return t.timetuple()

def main(ff=f):
    print ff
    print ff()

import time
main()
time.sleep(3)
main()

Here, the optional parameter is the function for datetime now - no parentheses, as @jonsharpe was recommending. 这里,可选参数现在是datetime的函数 - 没有括号,正如@jonsharpe所推荐的那样。 Calling f calls the default function, and calling it twice returns two different times: 调用f调用默认函数,并调用它两次返回两次不同的时间:

>>> import datetime
>>> def f(t=datetime.datetime.now):
...     return t()
... 
>>> f()
datetime.datetime(2015, 6, 21, 0, 6, 10, 698000)

>>> f()
datetime.datetime(2015, 6, 21, 0, 6, 12, 269000)

Or you can pass in another function, here a test one, and override t . 或者你可以传入另一个函数,这里是测试函数,并覆盖t Calling f() calls the function passed in: 调用f()调用传入的函数:

>>> def test():
...     return "hi"
... 
>>> f(t=test)
'hi'

定义函数时,默认参数值仅计算一次。

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

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