1

I am passing lambda to class and getting the same result of different objects of class. Here is my code.

from datetime import datetime

class Test:
    def __init__(self,fun):
        self.fun=fun

    def getDate(self):
        return self.fun(datetime.now())

hour=1
minute=30
t1 = Test(lambda x:x.replace(hour=hour,minute=minute))
hour=2
minute=30
t2 = Test(lambda x:x.replace(hour=hour,minute=minute))
print(t1.getDate())
print(t2.getDate())

Output:

2020-02-06 02:30:13.293611
2020-02-06 02:30:13.293659

Expected output:

2020-02-06 01:30:13.293611
2020-02-06 02:30:13.293659

1 Answer 1

3

Your variables hour and minute change before the lambda is called.

hour = 1
minute = 30

# the values of `hour` and `minute` right now are irrelevant
t1 = Test(lambda x: x.replace(hour=hour, minute=minute))

hour=2
minute=30

# the values of `hour` and `minute` right now are irrelevant
t2 = Test(lambda x: x.replace(hour=hour, minute=minute))

# the values of `hour` and `minute` RIGHT NOW are relevant
# and RIGHT NOW they are 2 and 30, respectively
print(t1.getDate())
print(t2.getDate())

The lambda references the variables, it does not copy their values. In other words, the values at the time of execution of the lambda functions are used, not the values at the time of setting them up.

Your options:

  • Hard-code the values in the lambda:

    t1 = Test(lambda x: x.replace(hour=1, minute=30))
    
  • Change the order of execution. Call the lambda before you change the values of hour and minute.

    hour1 = 1
    minute1 = 30
    
    t1 = Test(lambda x: x.replace(hour=hour, minute=minute))
    print(t1.getDate())
    
    hour1 = 2
    minute1 = 30
    
  • Use different variable names for each lambda.

    hour1 = 1
    minute1 = 30
    
    t1 = Test(lambda x: x.replace(hour=hour1, minute=minute1))
    print(t1.getDate())
    
  • Use different scopes to avoid that the lambdas reference the same hour and minute, e.g. by using a function. Essentially that's like using different variable names.

    def helper_function(hour, minute)
        return Test(lambda x: x.replace(hour=hour, minute=minute))
    
    t1 = helper_function(1, 30)
    t2 = helper_function(2, 30)
    
    print(t1.getDate())
    print(t2.getDate())
    

Using different scopes probably is the most elegant approach.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.