我无意中发现了一些意想不到的东西,这可能是我在Python或Django中误解的一些基本内容。
我在模型类中有一个静态方法来返回用户提供的日期,或者返回今天的日期:
@staticmethod
# By default return today's date or the date provided
def get_start_date(**kwargs):
startDate = kwargs.get('startDate', datetime.date.today())
return startDate
我决定重写它,使该方法将startDate作为默认参数。但是,默认的日期不是今天的日期,而是Django web服务器第一次启动的日期。为什么会这样呢?方法被执行,我已经确认startDate没有在调用中提供,即使我知道在代码的其他地方没有使用的变量被输入到参数中,它仍然返回Django第一次运行的日期。
def get_start_date(startDate=datetime.date.today(), notUsed=datetime.date.today(), **kwargs):
print(startDate, notUsed, datetime.date.today())
return startDate
>>> 2022-06-23 2022-06-23 2022-06-24
Python的默认参数在定义函数时求值一次,而不是每次调用函数时都求值。这意味着,如果您使用可变的默认参数并对其进行了修改,那么您将并且已经在将来对该函数的所有调用中对该对象进行了修改。
因此,将函数定义更改为
def my_function(start_date=datetime.date.today()):
# do something
def my_function(start_date=None):
if start_date is None:
start_date = datetime.date.today()
# do something