【问题标题】:Reference issue in lambda function in pythonpython中lambda函数的参考问题
【发布时间】:2020-02-06 12:00:39
【问题描述】:

我将 lambda 传递给类并从类的不同对象中获得相同的结果。这是我的代码。

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

【问题讨论】:

    标签: python-3.x lambda


    【解决方案1】:

    您的变量 hourminute 在调用 lambda 之前 更改。

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

    lambda 引用变量,它不复制它们的值。换句话说,使用的是执行 lambda 函数时的值,而不是设置它们时的值。

    您的选择:

    • 对 lambda 中的值进行硬编码:

      t1 = Test(lambda x: x.replace(hour=1, minute=30))
      
    • 更改执行顺序。在更改 hourminute 的值之前调用 lambda。

      hour1 = 1
      minute1 = 30
      
      t1 = Test(lambda x: x.replace(hour=hour, minute=minute))
      print(t1.getDate())
      
      hour1 = 2
      minute1 = 30
      
    • 为每个 lambda 使用不同的变量名。

      hour1 = 1
      minute1 = 30
      
      t1 = Test(lambda x: x.replace(hour=hour1, minute=minute1))
      print(t1.getDate())
      
    • 使用不同的范围来避免 lambda 引用相同 hourminute,例如通过使用一个函数。本质上,这就像使用不同的变量名。

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

    使用不同的作用域可能是最优雅的方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-05-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-02
      • 2019-02-05
      相关资源
      最近更新 更多