【问题标题】:python: alternative to anonymous functionspython:匿名函数的替代品
【发布时间】:2023-04-01 18:02:01
【问题描述】:

Python 不支持复杂的匿名函数。有什么好的选择?例如:

class Calculation:
    def __init__(self, func):
        self.func = func

    def __call__(self, data):
        try:
        # check if the value has already been calculated
        # if it has, it would be cached under key = self.func
            return data[self.func]
        except KeyError:
            pass # first-time call; calculate and cache the values
        data[self.func] = self.func(data)
        return data[self.func]

# with a simple function, which can be represented using lambda, this works great
f1 = Calculation(lambda data : data['a'] * data['b'])

# with a complicated function, I can do this:
def f2_aux:
   # some complicated calculation, which isn't suitable for a lambda one-liner
f2 = Calculation(f2_aux) 

这是一个合理的设计吗?

如果是这样,有没有办法避免我在模块中定义的每个 f* 的 f*_aux 的丑陋?

更新:

使用示例:

d = {'a' : 3, 'b' : 6}

# computes 3 * 6
# stores 18 in d under a key <function <lambda> at ...>
# returns 18
f1(d)

# retrieves 18 from d[<function <lambda> at ...>]
# returns 18, without having to recalculate it
f1(d)

更新:

只是为了我的理解,我添加了一个使用内部函数的版本。

def memoize(func):
    def new_func(data):
        try:
        # check if the value has already been calculated
        # if it has, it would be cached under key = self.func
            return data[func]
        except KeyError:
            pass # first-time call; calculate and cache the values
        data[func] = func(data)
        return data[func]
    return new_func

@memoize
def f1(data):
  return data['a'] * data['b']

【问题讨论】:

  • 不,这不是一个合理的设计。你似乎在做记忆(这与匿名函数无关),而且做得很糟糕。 f1 = lambda a: expression 始终与 def f1(a): return expression 完全相同。 This is a good memoization decorator to study。顺便说一句,@decorator def function: pass 总是与def function: pass; function = decorator(function) 完全相同
  • 糟糕的是你的记忆器坏了。结果缓存 data 也是您的函数的参数...
  • @FrancisAvila:我打算在字典元素data[f] 中缓存f(data) 的值。我知道传递给我的 data 永远不会使用这样的键 - 也不应该发生与另一个函数的冲突,因为另一个函数的值将缓存在另一个键下。看起来它有效(技术上);问题只是在不必要的混乱代码中吗?
  • @FrancisAvila 好吧,data(比如字典)被传递给函数:f1(data)。只要调用者需要,调用者就会保持data 处于活动状态,如果他们再次调用f1(data),缓存就会启动。(至少我希望它是这样工作的。)
  • memoization 是不透明的:你在 memoized 函数(单参数字典)上强加了一个接口,并要求调用代码与参数和所有缓存值共享相同的命名空间。如果调用代码要更改示例中的“a”键,那么 data 中的每个功能键现在都有一个过时的缓存值!

标签:
python
lambda
python-3.x
anonymous-function