【问题标题】:Python ValueError when using local function in map在地图中使用本地函数时出现 Python ValueError
【发布时间】:2014-01-11 12:04:53
【问题描述】:

我正在尝试创建一个包含已由不同函数处理的数据的列表。下面的代码不起作用,因为a和b这两个函数不在map函数的作用域内

def outer_func():
    def a():
        return "Something"
    def b():
        return "Something else"
    map(lambda x: eval(x)(), ['a', 'b'])

我尝试将函数包装在一个类中,下面的代码运行良好。

class fcontainer():
    def a(self):
        return "Something"

    def b(self):
        return "Something else"

def test():
    f = fcontainer()
    return map(lambda x: getattr(f, x)(), ['a', 'b'])

现在,我的问题是:

  1. 为什么 map 函数中不存在 a 和 b?
  2. 是否有“正确”的方式来做我想做的事情?
  3. 最后我应该坐下来把头围在装饰器上吗? :)

谢谢!

更新:第一个示例可以通过首先在 outer_func 范围内获取函数,然后使用 map 来工作:

functions = [eval(i) for i in ['a', 'b']]
return map(lambda x: x(), functions)

这可行,但它是两行而不是一行 >:|

【问题讨论】:

    标签: python function namespaces


    【解决方案1】:

    是否需要有一个字符串列表(['a', 'b'])?也许你最好把函数对象直接放入列表中:[a, b]

    return map(lambda x: x(), [a, b])
    

    对我来说似乎很容易。

    如果你想把它当成装饰器,那也不会容易得多:

    def outer_func():
        funcs = []
        def funcapp(func): # so that a and b are still in place...
            funcs.append(func)
            return func
        @funcapp
        def a():
            return "Something"
        @funcapp
        def b():
            return "Something else"
        return funcs
    

    【讨论】:

    • 为什么要自己上课呢? @myList.append
    • @Eric 有时我们倾向于监督最简单的事情。谢谢。
    • 话虽如此,使用@myList.append 会导致a 成为None,但在这种情况下并不重要
    • @Eric 对,这就是为什么可以进行此更改的原因。
    • 感谢您提供非常有启发性的回答! return map(lambda x: x(), [a, b]) 确实可以解决问题,而且很干净!我想我是另一个忽略最简单的事情的例子:)。
    【解决方案2】:

    您需要确保eval 在正确的上下文中执行,方法是在outer_func() 中给它globalslocals

    def outer_func():
        def a():
            return "Something"
        def b():
            return "Something else"
        map(lambda x, g=globals(), l=locals(): eval(x, g, l)(), ['a', 'b'])
    

    话虽如此,eval 可能无法解决您的问题

    【讨论】:

    • 感谢您的回答!在此之前,我从来不明白必须将本地人作为参数提供给 eval 的意义。
    【解决方案3】:

    在 python 中,我们有一个特殊功能,您可以像传递变量一样传递函数。

    您的第一种方法几乎是正确的,.. 有点错过:)

    >>> def outer_func():
    ...     def a():
    ...         return "Something"
    ...     def b():
    ...         return "Something else"
    ...     print map(lambda x: x(), [a, b])
    ...
    >>> outer_func()
    ['Something', 'Something else']
    

    eval 真的很好,但就像你遇到的那样,它有风险

    如果将它用于您的第二种方法,它将起作用。

    >>> def test():
    ...     f = fcontainer()
    ...     return map(lambda x: x(), [f.a, f.b])
    ...
    >>> test()
    ['Something', 'Something else']
    

    现在,回答您的问题:

    第一季度。为什么 map 函数中不存在 a 和 b?

    MAP 功能很特别。它不会打扰超出其范围的内容。这使它更快。检查下面的代码以了解。

    >>> dir() # used to check local variables/function defined already.
    ['__builtins__', '__doc__', '__name__', '__package__', 'outer_func']
    >>> map( lambda x: dir() , range(5))
    [['x'], ['x'], ['x'], ['x'], ['x']]
    >>> # as you can see within MAP, outer_func is missing.
    

    第二季度。有没有“正确”的方法来做我想做的事情?

    有一种更简单的方法:)

    第三季度。我最终是否应该坐下来围观装饰器?

    我想你现在已经得到了答案。所以暂时没有装饰

    希望对你有帮助:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-09
      • 2018-02-07
      • 2019-06-03
      • 2017-02-04
      • 2017-06-11
      • 2017-10-02
      • 1970-01-01
      • 2023-01-02
      相关资源
      最近更新 更多