Справочная проблема в лямбда-функции в python - PullRequest
1 голос
/ 06 февраля 2020

Я передаю лямбду в класс и получаю одинаковый результат для разных объектов класса. Вот мой код.

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())

Вывод:

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

Ожидаемый вывод:

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

1 Ответ

2 голосов
/ 06 февраля 2020

Ваши переменные hour и minute изменяют до . Вызывается лямбда.

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())

Лямбда ссылается на переменные, но не копирует их значения. Другими словами, используются значения во время выполнения лямбда-функций, а не значения во время их установки.

Ваши параметры:

  • Жесткий код значений в лямбде:

    t1 = Test(lambda x: x.replace(hour=1, minute=30))
    
  • Изменить порядок исполнения. Вызовите лямбду, прежде чем изменить значения hour и minute.

    hour1 = 1
    minute1 = 30
    
    t1 = Test(lambda x: x.replace(hour=hour, minute=minute))
    print(t1.getDate())
    
    hour1 = 2
    minute1 = 30
    
  • Используйте разные имена переменных для каждой лямбды.

    hour1 = 1
    minute1 = 30
    
    t1 = Test(lambda x: x.replace(hour=hour1, minute=minute1))
    print(t1.getDate())
    
  • Используйте разные области видимости, чтобы лямбды не ссылались на одинаковых hour и minute, например, с помощью функции. По сути, это похоже на использование разных имен переменных.

    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())
    

Использование разных областей видимости, вероятно, является наиболее элегантным подходом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...