【问题标题】:Python:dict comprehension and eval function variable scopePython:dict理解和eval函数变量范围
【发布时间】:2020-09-24 06:30:02
【问题描述】:

代码 1:for 循环

def foo():
    one = '1'
    two = '2'
    three = '3'
    d = {}
    for name in ('one', 'two', 'three'):
        d[name] = eval(name)
    print(d)

foo()

输出:

{'一':'1','二':'2','三':'3'}

代码 2:听写理解

def foo():
    one = '1'
    two = '2'
    three = '3'
    print({name: eval(name) for name in ('one', 'two', 'three')})

foo()

输出:

NameError: name 'one' 未定义

代码3:添加全局关键字

def foo():
    global one, two, three  # why?
    one = '1'
    two = '2'
    three = '3'
    print({name: eval(name) for name in ('one', 'two', 'three')})

foo()

输出:

{'一':'1','二':'2','三':'3'}

字典推导和生成器推导创建自己的本地范围。根据闭包的定义(或者这里不是闭包),但是为什么Code 2不能访问外部函数foo的变量one[,two,three]呢?但是,代码3可以通过将变量one[,two,three]设置为全局来成功创建字典?

是不是因为eval 函数和dict 理解有不同的作用域?

希望有人帮助我,我将不胜感激!

【问题讨论】:

    标签: python-3.x scope global-variables dictionary-comprehension


    【解决方案1】:

    要了解发生了什么,试试这个:

    def foo():
        global one
        one = '1'
        two = '2'
        print({'locals, global': (locals(), globals()) for _ in range(1)})
    
    foo()
    

    输出

    {'locals, global': ({'_': 0, '.0': <range_iterator object at ...>},
                        {'__name__': '__main__', '__package__': None, ..., 'one': '1'})}
    

    内置的eval(expression)eval(expression[, globals[, locals]]) 的快捷方式。

    正如您在前面的输出中看到的,locals() 不是函数的本地符号表,因为列表/字典推导有自己的范围(例如,请参阅 https://bugs.python.org/msg348274)。

    要获得您期望的输出,您只需将函数的本地符号表传递给eval

    def bar():
        one = '1'
        two = '2'
        three = '3'
        func_locals = locals() # bind the locals() here
        print({name: eval(name, globals(), func_locals) for name in ('one', 'two', 'three')})
    
    bar()
    

    输出

    {'one': '1', 'two': '2', 'three': '3'}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-25
      • 1970-01-01
      • 2020-07-22
      • 2021-12-18
      相关资源
      最近更新 更多