在地图中使用本地函数时的Python ValueError

时间:2014-01-11 12:04:53

标签: python function namespaces

我正在尝试制作一个包含已由不同功能处理的数据的列表。以下代码不起作用,因为两个函数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. 为什么地图功能中不存在a和b?
  2. 有没有'正确'的方法来做我想做的事情?
  3. 我最后是否应该坐下来围绕装饰师? :)
  4. 谢谢!

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

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

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

3 个答案:

答案 0 :(得分:4)

是否需要有一个字符串列表(['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

答案 1 :(得分:1)

您需要确保eval在正确的背景下执行,方法是在globals内提供localsouter_func()

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可能不是您问题的解决方案

答案 2 :(得分:0)

在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']

现在,问题:

<强> Q1。为什么地图函数中不存在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.

<强> Q2。是否有'正确'的方式来做我想做的事情?

有一种更简单的方法:)

<强> Q3。我是不是应该坐下来围绕装饰师?

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

希望这可以帮助你:)