评估无法理解列表

编程入门 行业动态 更新时间:2024-10-25 05:15:11
本文介绍了评估无法理解列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

请考虑以下假设代码:

class B(object): def __init__(self): self.b = 2 def foo(self): out1 = [eval('self.b')] # ok print(out1) # prints: [2] out2 = [eval(cmd) for cmd in ['self.b']] # fails print(out2) # NameError: name 'self' is not defined b = B() b.foo()

为什么对out1的语句没问题,而对于out2的语句却不行,它给出了错误未定义'自我'"?

Why is the statement for out1 ok, but not for out2, which gives the error "'self' is not defined"?

我正在学习Python,在尝试eval时遇到了这个问题.是的,我知道在此示例中使用eval是不合适的,但是仅出于以表面价值为例进行说明,有人可以解释为什么out2的语句会给出错误消息吗?似乎两个语句都应该起作用并给出相同的结果.

I am learning Python, and I came about this problem whilst experimenting about eval. Yes, I know the use of eval in this example is inappropriate, but just for the sake of taking this example at face value, can someone explain why the statement for out2 gives out the error message? It seems both statements should work and give the same result.

谢谢您的指导.

推荐答案

通过使用列表理解,您实际上定义了一个新范围.的确,如果我们将列表理解更改为:

By using list comprehension, you actually define a new scope. Indeed if we alter the list comprehension to:

out2 = [print(globals()) or print(locals()) or eval(cmd) for cmd in ['self.b']]

我们强制Python在进行eval(..)调用之前先打印局部变量和全局变量,然后获得类似以下内容的信息:

we force Python to print the local and global variables before making the eval(..) call, and we obtain something like:

{'__builtins__': <module 'builtins' (built-in)>, '__name__': '__main__', '__loader__': <class '_frozen_importlib.BuiltinImporter'>, 'b': <__main__.B object at 0x7f406f55d4a8>, '__doc__': None, '__package__': None, 'B': <class '__main__.B'>, '__spec__': None} {'.0': <list_iterator object at 0x7f406f55df28>, 'cmd': 'self.b'}

因此,作为局部变量,我们只有.0和cmd.

So as local variables we only have a .0 and a cmd.

不过,您可以使用以下方法将self传递给列表理解:

You can however pass self to the list comprehension by using:

globs = globals() locs = locals() out2 = [eval(cmd,globs,locs) for cmd in ['self.b']]

因此,现在eval(..)将使用在函数范围内定义的局部变量和全局变量.由于我们使用locs和globs. Python将对这些词典的引用传递给eval(..)调用.

So now eval(..) will use the local and global variables as defined in the scope of the function. Since we use locs and globs. Python will pass references to these dictionaries to the eval(..) call.

最后,像每次使用eval(..)一样发出警告:eval是危险功能.最好仅在确实需要时使用它.

Finally a warning as with every use of eval(..): eval is a dangerous function. You better use it only if you really need it.

此附加范围的附加副作用(在 python-3.x )是循环变量不会 泄漏:清除列表理解cmd之后:您将无法再访问它(通常它将保存已处理的最后一个元素).例如:

An additional side effect of this additional scope (introduced in python-3.x) is that the loop variable does not leak: after the list comprehension cmd is cleaned up: you can no longer access it (usually it would hold the last element it has handled). For example:

>>> [x for x in range(10)] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> x Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'x' is not defined

更多推荐

评估无法理解列表

本文发布于:2023-07-27 14:01:12,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1222743.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:列表

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!