栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

使用python3的列表生成器表达式中未定义的全局变量,可与python2一起使用,需要进行哪些更改?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

使用python3的列表生成器表达式中未定义的全局变量,可与python2一起使用,需要进行哪些更改?

正如Wooble所说,问题是类没有词法范围(实际上,在Python
2
或Python
3中)。相反,它们具有不构成范围的本地 名称空间 。这意味着类定义中的表达式可以访问名称空间的内容:

class C:    a = 2    b = a + 2    # b = 4

但在类主体中引入的范围 无法 访问其名称空间:

class C:    a = 2    def foo(self):        return a    # NameError: name 'a' is not defined, use return self.__class__.a

Python 2和Python 3之间的区别在于,在Python 2中,列表推导 不会 引入新的作用域:

[a for a in range(3)]print a    # prints 2

而在Python 3中,它们执行以下操作:

[a for a in range(3)]print(a)    # NameError: name 'a' is not defined

在Python 3中对此进行了更改,其原因有两个,包括使列表推导的行为与生成器表达式(genexps)相同。

(a for a inrange(3))
在Python 2和Python 3中都有自己的作用域。

因此,在类的主体内,Python 2 genexp或Python 3 listcomp或genexp引入了新作用域,因此无法访问类定义本地名称空间。

赋予genexp / listcomp访问类定义名称空间名称的方法是使用函数或lambda引入新作用域:

class C:    a = 2    b = (lambda a=a: [a + i for i in range(3)])()

eval
问题

您的

eval
示例的问题在于
eval
,默认情况下会在本地范围内评估其参数;因为Python
2列表理解具有共享封闭范围的上述行为,因此
eval
可以访问方法范围,但是genexp或Python 3
listcomp局部范围仅具有编译器可以从封闭范围中得知的内容(因为genexp / listcomp范围是一个闭包):

def bar(x):    return list(eval('x') + x for i in range(3))bar(5)  # returns [10, 10, 10]def baz(x):    return list(eval('x') for i in range(3))baz(5)  # NameError: name 'x' is not defined

正如Martijn所说的,而不是

eval
您应该使用
getattr



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/641679.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号