Exec和List Comprehension不能正常工作?

时间:2018-01-05 03:29:45

标签: python python-3.x exec list-comprehension

我是日本Python新手。 当我攻击Python代码时,我发现了一个有趣的现象/ 我的目的是调查执行功能,列表理解和范围的行为。

以下代码成功运行。

#! /usr/bin/env python3
# test1.py

exec ('''
book = {"Apple":[120,15], "Orange":[95,32], "Banana":[60,71]}
print("↓↓globals()↓↓")
print(globals())
print()
print("↓↓locals()↓↓")
print(locals())
print()

print("↓↓One-Values↓↓")
print(book["Apple"])
print()

keys = [x for x in list(book.keys())]
print("↓↓All-Keys↓↓")
print(keys)
print()

values = [book[x] for x in list(book.keys())]
print("↓↓All-Values↓↓")
print(values)
''')

结果如我所料:

$ test1.py
↓↓globals()↓↓
{'__builtins__': <module 'builtins' (built-in)>, '__doc__': None, '__cached__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x7f7bc7387588>, 'builtins': <module 'builtins' (built-in)>, '__name__': '__main__', 'book': {'Banana': [60, 71], 'Orange': [95, 32], 'Apple': [120, 15]}, '__file__': './test1.py', '__spec__': None}

↓↓locals()↓↓
{'__builtins__': <module 'builtins' (built-in)>, '__doc__': None, '__cached__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x7f7bc7387588>, 'builtins': <module 'builtins' (built-in)>, '__name__': '__main__', 'book': {'Banana': [60, 71], 'Orange': [95, 32], 'Apple': [120, 15]}, '__file__': './test1.py', '__spec__': None}

↓↓One-Values↓↓
[120, 15]

↓↓All-Keys↓↓
['Banana', 'Orange', 'Apple']

↓↓All-Values↓↓
[[60, 71], [95, 32], [120, 15]]

成功查找词典。

print(book["Apple"])
===>
[120, 15]

第一个列表理解也被成功评估。

keys = [x for x in list(book.keys())]
===>
['Orange', 'Apple', 'Banana']

第二个列表理解也经常被评估。

values = [book[x] for x in list(book.keys())]
===>
[[60, 71], [95, 32], [120, 15]]

但是当我尝试从用户定义的函数调用exec函数时:

#! /usr/bin/env python3
# test2.py

def exec_test(s):
    exec(s)

exec_test ('''
book = {"Apple":[120,15], "Orange":[95,32], "Banana":[60,71]}
print("↓↓globals()↓↓")
print(globals())
print()
print("↓↓locals()↓↓")
print(locals())
print()

print("↓↓One-Values↓↓")
print(book["Apple"])
print()

keys = [x for x in list(book.keys())]
print("↓↓All-Keys↓↓")
print(keys)
print()

values = [book[x] for x in list(book.keys())]
print("↓↓All-Values↓↓")
print(values)
''')

结果不同:

$ test2.py
↓↓globals()↓↓
{'__cached__': None, '__package__': None, '__file__': './test2.py', '__builtins__': <module 'builtins' (built-in)>, 'exec_test': <function exec_test at 0x7f7aaa88c2f0>, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x7f7aaa927588>, '__doc__': None, '__spec__': None, 'builtins': <module 'builtins' (built-in)>, '__name__': '__main__'}

↓↓locals()↓↓
{'book': {'Orange': [95, 32], 'Apple': [120, 15], 'Banana': [60, 71]}, 's': '\nbook = {"Apple":[120,15], "Orange":[95,32], "Banana":[60,71]}\nprint("↓↓globals()↓↓")\nprint(globals())\nprint()\nprint("↓↓locals()↓↓")\nprint(locals())\nprint()\n\nprint("↓↓One-Values↓↓")\nprint(book["Apple"])\nprint()\n\nkeys = [x for x in list(book.keys())]\nprint("↓↓All-Keys↓↓")\nprint(keys)\nprint()\n\nvalues = [book[x] for x in list(book.keys())]\nprint("↓↓All-Values↓↓")\nprint(values)\n'}

↓↓One-Values↓↓
[120, 15]

↓↓All-Keys↓↓
['Orange', 'Apple', 'Banana']

Traceback (most recent call last):
  File "./test2.py", line 33, in <module>
    ''')
  File "./test2.py", line 10, in exec_test
    exec(s)
  File "<string>", line 19, in <module>
  File "<string>", line 19, in <listcomp>
NameError: name 'book' is not defined

成功查找词典。

print(book["Apple"])
===>
[120, 15]

第一个列表理解也被成功评估。

keys = [x for x in list(book.keys())]
===>
['Orange', 'Apple', 'Banana']

但由于NameError,第二个列表推导被评估失败。

values = [book[x] for x in list(book.keys())]
===>
Traceback (most recent call last):
  File "./test2.py", line 33, in <module>
    ''')
  File "./test2.py", line 10, in exec_test
    exec(s)
  File "<string>", line 19, in <module>
  File "<string>", line 19, in <listcomp>
NameError: name 'book' is not defined

为什么?

我的问题如下:

Q1:为什么全球book消失了?

如果你写了:

exec("""
hash = {"key1":"value1","key2":"value2",...}
""")

散列位于globals()locals()

但如果你写了:

def do_exec(s) {
  exec(s)

do_exec("""
hash = {"key1":"value1","key2":"value2",...}
""")

哈希只在locals()

为什么?

Q2:为什么book[x]无法找到book,而book.keys()可以找到它?

在test1.py中,两个列表理解都可以正常工作。

keys = [x for x in list(book.keys())]

values = [book[x] for x in list(book.keys())]

但是在test2.py中,只有第二个列表解析变为NameError。

我认为原因是book仅在test2.py中是本地的。并且列表推导使其自己的范围因此找不到名称book

但是,为什么第一个列表理解会安全地运行? 换句话说,为什么book.keys()方法调用可以找到名称book

这些是我的问题。 请给我任何建议。 非常感谢你提前!

我的环境:

$ python3 -V
Python 3.5.2

$ uname -a
Linux DESKTOP-AHPUUO5 4.4.0-43-Microsoft #1-Microsoft Wed Dec 31 14:42:53 PST 2014 x86_64 x86_64 x86_64 GNU/Linux

0 个答案:

没有答案