Reputation: 679
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
Upvotes: 1
Views: 1138
Reputation: 338228
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.
Upvotes: 3