1

While attempting to optimize my current code, I have this situation where my function by default gets the current time, and it was done using a very basic, and not elegant way:

from datetime import datetime
.
.
.
def generateGraph(self, fromTime, toTime = None):
    if toTime is None:
        toTime = datetime.now()
    .
    .

Thus, I had started testing going with something such as this:

def generateGraph(self, fromTime, toTime = datetime.now()):
    .
    .

However, since my application was a little large (and the slight difficulty of testing this application specifically) I made a short code snippet that I have tested, as follows:

X = 20

def setValue():
    return X
def myFunction(value=setValue()):
    print(value)
    
a = myFunction()
X = 15
b = myFunction()

I expected the output to be: 20 15

However, I had the output as: 20 20

Is this value being assigned during the function declaration? Or is it assigned at the moment the "def" statement is being read? I am a bit unclear on how this might affect my application, and how in this example code snippet, I can achieve what I am looking for (Since I used X just as a replacement for datetime.now(), for simplicity/visibility sake).

Zaid Al Shattle
  • 1,454
  • 1
  • 12
  • 21
  • It gave a few hints, but I would say the main question is still not completely answered, or at least I think so – Zaid Al Shattle Jul 15 '21 at 14:41
  • the main idea is that function default arguments are evaluated once during function definition and `datetime.now` is not a "constant" thing, it changes over execution of your program, hence you should recalculate it on each call – Azat Ibrakov Jul 15 '21 at 14:43
  • So, there is no method to achieve what I was trying to do? I will have to stick to the original implementation? – Zaid Al Shattle Jul 15 '21 at 14:50
  • yes, if you want your `toTime` to be a fresh new `datetime.now()` on each call (when it's not explicitly passed) – Azat Ibrakov Jul 15 '21 at 14:53
  • Disappointing but makes sense, I will keep looking for a cleaner implementation because I REALLY hate having to use it, but until then I will keep the original implementation. Thank you. – Zaid Al Shattle Jul 15 '21 at 14:56

1 Answers1

1

You want to follow the pattern of setting it to None and then populating the value if not set. The value in the function definition arguments will only get evaluated once, so you can't and shouldn't assume to update default arguments this way:

def myFunction(value=None):
    if value is None:
        value = setValue()
    print(value)
flakes
  • 21,558
  • 8
  • 41
  • 88