【发布时间】:2019-10-26 22:59:26
【问题描述】:
这是我前几天正在解决的随机问题。给定一个以秒为单位的年龄,必须计算一个人在特定星球上的年龄。我试图动态地向我的类添加新方法并想出了这个解决方案:
class MyClass(object):
year_in_seconds_on_earth = 31557600
planets = {
'earth': 1,
'mercury': 0.2408467,
'venus': 0.61519726,
'mars': 1.8808158,
'jupiter': 11.862615,
'saturn': 29.447498,
'uranus': 84.016846,
'neptune': 164.79132
}
def __init__(self, seconds):
self.seconds = seconds
for planet in self.planets:
func = lambda: self._on_planet(planet)
self.__setattr__('on_' + planet, func)
# self._add_method(planet)
# def _add_method(self, planet):
# func = lambda: self._on_planet(planet)
# self.__setattr__('on_' + planet, func)
def _on_planet(self, planet):
return round(self.seconds / self.year_in_seconds_on_earth / self.planets[planet], 2)
print(MyClass(2134835688).on_mercury())
所以当我从单独的方法(注释部分)调用lambda 和setattr 时,它工作得非常好。但是从__init__调用它们时,调用on_mercury、on_mars或其他类似方法时只使用最后一个值neptune。
我知道在__init__ 中,它从外部函数的闭包中获取值,而planets 的值在循环中被更改。但我不太明白这两种情况到底发生了什么。以下是一些问题:
- 它是传递给
_add_method的行星变量的副本吗? - 为什么传递给
_add_method的值没有变化,而直接在循环中传递时会发生变化?
【问题讨论】:
-
@Sayse 他们是,但他们都应该有不同的论点。 lambdas 中的 python 参数绑定一定有什么可疑之处。
-
@MT13 你用调试器运行过吗?
-
我认为这个线程密切相关:stackoverflow.com/questions/10452770/…
标签: python python-3.x lambda nested-function