Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/joomla/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 评估呼叫lambda don';我看不见自己_Python - Fatal编程技术网

Python 评估呼叫lambda don';我看不见自己

Python 评估呼叫lambda don';我看不见自己,python,Python,下面是一个简单的代码,说明了问题的本质: class test: def __init__(self): self.var = 0 def set(self, val): self.var = val print eval('map(lambda x: self.var*x, [1,2,3,4,5])') f = test() f.set(10) 上面说 NameError: global name 'self' is not d

下面是一个简单的代码,说明了问题的本质:

class test:
    def __init__(self):
        self.var = 0
    def set(self, val):
        self.var = val
        print eval('map(lambda x: self.var*x, [1,2,3,4,5])')
f = test()
f.set(10)
上面说

NameError: global name 'self' is not defined
我知道很多人不喜欢eval,但在我的例子中,我不得不使用它,因为它根据用户在程序执行期间输入的字符串执行数学公式。 非常感谢您的任何建议!提前谢谢

试试看:

eval('map(lambda x, self=self: self.var*x, [1,2,3,4,5])')

奇怪的
self=self
将创建一个
self
的副本,从外部上下文复制到内部上下文(lambda表达式的“主体”)。

虽然我确信有一种不使用eval的方法可以做到这一点,但您是否尝试过使用字符串格式

eval('map(lambda x: %s*x, [1,2,3,4,5])'%self.var)

这是一个棘手的局面。首先,作为解决方法,您可以使用:

class test:
    def __init__(self):
        self.var = 0
    def set(self, val):
        self.var = val
        print eval('map(lambda x,self=self: self.var*x, [1,2,3,4,5])')
f = test()
f.set(10)
原因不容易解释。。。但是让我们试试看

当你写作时

 lambda x: self.var * x
创建的是一个“闭包”,它将当前变量“self”捕获为lambda表达式中的非局部变量,因为self在当前环境中是局部变量

当此lambda由
eval
生成时,但是此局部变量
self
eval
中不可见,因此生成的lambda函数将引用在这种情况下不存在的全局变量
self

eval()还支持分别设置全局变量和局部变量,以便执行以下操作:

class test:
    def __init__(self):
        self.var = 0
    def set(self, val):
        self.var = val
        print eval('map(lambda x: self.var*x, [1,2,3,4,5])', dict(globals().items() + [('self', self)]))
f = test()
f.set(10)

更新:以上示例现在维护以前的全局和局部变量。

更通用的答案是将局部变量传递到eval环境中

支持两个附加参数,即全局变量和局部变量。因此,例如,您可以通过传递以下消息来解决问题,而无需更改函数:

eval(map(lambda x: self.var*x + myvar, [1,2,3,4,5]), dict(self=self, myvar=123))

好办法!这就是我要找的!:)非常感谢你@aliko如果答案解决了你的问题,你应该接受它(左边计票下面的“V”标记)。我希望我可以将这里的所有消息标记为已接受,但不幸的是,我只能标记一条…(让它成为第一个正确答案:)“数学公式”如
\uu import\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
?@dan04:您的公式中一定有错误。它在Windows上不起作用:),而这种方法正在起作用!Python是关于选择的:)我没想到会在几分钟内收到如此有用的答案。而你的是最基本的…)这是一个很好的提问的地方!:)您收到了有用的答案,因为您以简化的形式清楚地陈述了您的问题,解释了您为什么要做您正在做的事情,并且因为问题很有趣。如果你所有的问题都是这样,你会得到很好的回答。此外,如果你还不知道,当你决定哪个答案是你问题的最佳解决方案时,在数字和箭头下方有一个小复选标记,可以让你将其标记为“已接受”。这种方法的唯一缺点是它对eval隐藏全局值。@aliko谢谢,你是对的。我已经更新了我的示例以维护以前的全局。这个解决方案的优点是不必更改lambda签名,很好。