Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/321.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
Can';在Python 3中,在列表理解中不使用locals()?_Python_Python 3.x_Scope_List Comprehension_Scoping - Fatal编程技术网

Can';在Python 3中,在列表理解中不使用locals()?

Can';在Python 3中,在列表理解中不使用locals()?,python,python-3.x,scope,list-comprehension,scoping,Python,Python 3.x,Scope,List Comprehension,Scoping,以下内容适用于Python 2,但不适用于Python 3。在Python3中有没有访问局部变量的方法?还是这些案例的替代解决方案 [('{name_var}_{i:02d}of{maxpg:02d}.{date_var}').format(i, **locals()) for i in range(start, end)] >>> def g(): return [l for l in (locals(),)] ... >>> dis(g) 1

以下内容适用于Python 2,但不适用于Python 3。在Python3中有没有访问局部变量的方法?还是这些案例的替代解决方案

[('{name_var}_{i:02d}of{maxpg:02d}.{date_var}').format(i, **locals()) 
  for i in range(start, end)]
>>> def g(): return [l for l in (locals(),)]
... 
>>> dis(g)
  1           0 LOAD_CONST               1 (<code object <listcomp> at 0x7f5b65cb8930, file "<stdin>", line 1>)
              2 LOAD_CONST               2 ('g.<locals>.<listcomp>')
              4 MAKE_FUNCTION            0
              6 LOAD_GLOBAL              0 (locals)
              8 CALL_FUNCTION            0
             10 BUILD_TUPLE              1
             12 GET_ITER
             14 CALL_FUNCTION            1
             16 RETURN_VALUE
Python 3中的错误:

>>> def g(): return [l for l in (locals(),)]
... 
>>> dis(g)
  1           0 LOAD_CONST               1 (<code object <listcomp> at 0x7f5b65cb8930, file "<stdin>", line 1>)
              2 LOAD_CONST               2 ('g.<locals>.<listcomp>')
              4 MAKE_FUNCTION            0
              6 LOAD_GLOBAL              0 (locals)
              8 CALL_FUNCTION            0
             10 BUILD_TUPLE              1
             12 GET_ITER
             14 CALL_FUNCTION            1
             16 RETURN_VALUE
KeyError:“本地变量”

>>> def g(): return [l for l in (locals(),)]
... 
>>> dis(g)
  1           0 LOAD_CONST               1 (<code object <listcomp> at 0x7f5b65cb8930, file "<stdin>", line 1>)
              2 LOAD_CONST               2 ('g.<locals>.<listcomp>')
              4 MAKE_FUNCTION            0
              6 LOAD_GLOBAL              0 (locals)
              8 CALL_FUNCTION            0
             10 BUILD_TUPLE              1
             12 GET_ITER
             14 CALL_FUNCTION            1
             16 RETURN_VALUE
下面是上面的一个简单玩具示例(适用于Python 2,但不适用于Python 3)

>>> def g(): return [l for l in (locals(),)]
... 
>>> dis(g)
  1           0 LOAD_CONST               1 (<code object <listcomp> at 0x7f5b65cb8930, file "<stdin>", line 1>)
              2 LOAD_CONST               2 ('g.<locals>.<listcomp>')
              4 MAKE_FUNCTION            0
              6 LOAD_GLOBAL              0 (locals)
              8 CALL_FUNCTION            0
             10 BUILD_TUPLE              1
             12 GET_ITER
             14 CALL_FUNCTION            1
             16 RETURN_VALUE
Python 3中的错误:

>>> def g(): return [l for l in (locals(),)]
... 
>>> dis(g)
  1           0 LOAD_CONST               1 (<code object <listcomp> at 0x7f5b65cb8930, file "<stdin>", line 1>)
              2 LOAD_CONST               2 ('g.<locals>.<listcomp>')
              4 MAKE_FUNCTION            0
              6 LOAD_GLOBAL              0 (locals)
              8 CALL_FUNCTION            0
             10 BUILD_TUPLE              1
             12 GET_ITER
             14 CALL_FUNCTION            1
             16 RETURN_VALUE
KeyError:“本地变量”

>>> def g(): return [l for l in (locals(),)]
... 
>>> dis(g)
  1           0 LOAD_CONST               1 (<code object <listcomp> at 0x7f5b65cb8930, file "<stdin>", line 1>)
              2 LOAD_CONST               2 ('g.<locals>.<listcomp>')
              4 MAKE_FUNCTION            0
              6 LOAD_GLOBAL              0 (locals)
              8 CALL_FUNCTION            0
             10 BUILD_TUPLE              1
             12 GET_ITER
             14 CALL_FUNCTION            1
             16 RETURN_VALUE

正如@user2357112在注释中所解释的,列表理解在Python3中有自己的局部作用域(因此
locals()
dict)

>>> def g(): return [l for l in (locals(),)]
... 
>>> dis(g)
  1           0 LOAD_CONST               1 (<code object <listcomp> at 0x7f5b65cb8930, file "<stdin>", line 1>)
              2 LOAD_CONST               2 ('g.<locals>.<listcomp>')
              4 MAKE_FUNCTION            0
              6 LOAD_GLOBAL              0 (locals)
              8 CALL_FUNCTION            0
             10 BUILD_TUPLE              1
             12 GET_ITER
             14 CALL_FUNCTION            1
             16 RETURN_VALUE
比较:

>>> var=1
>>> [locals() for _ in range(1)]
[{'_': 0, '.0': <range_iterator object at 0x7f5b65cb7270>}]
>>> def g(): return [l for l in (locals(),)]
... 
>>> dis(g)
  1           0 LOAD_CONST               1 (<code object <listcomp> at 0x7f5b65cb8930, file "<stdin>", line 1>)
              2 LOAD_CONST               2 ('g.<locals>.<listcomp>')
              4 MAKE_FUNCTION            0
              6 LOAD_GLOBAL              0 (locals)
              8 CALL_FUNCTION            0
             10 BUILD_TUPLE              1
             12 GET_ITER
             14 CALL_FUNCTION            1
             16 RETURN_VALUE
未调用
locals
函数。您可以在列表的代码中看到调用:

>>> dis(f.__code__.co_consts[1])
  1           0 BUILD_LIST               0
              2 LOAD_FAST                0 (.0)
        >>    4 FOR_ITER                10 (to 16)
              6 STORE_FAST               1 (_)
              8 LOAD_GLOBAL              0 (locals)
             10 CALL_FUNCTION            0
             12 LIST_APPEND              2
             14 JUMP_ABSOLUTE            4
        >>   16 RETURN_VALUE
>>> def g(): return [l for l in (locals(),)]
... 
>>> dis(g)
  1           0 LOAD_CONST               1 (<code object <listcomp> at 0x7f5b65cb8930, file "<stdin>", line 1>)
              2 LOAD_CONST               2 ('g.<locals>.<listcomp>')
              4 MAKE_FUNCTION            0
              6 LOAD_GLOBAL              0 (locals)
              8 CALL_FUNCTION            0
             10 BUILD_TUPLE              1
             12 GET_ITER
             14 CALL_FUNCTION            1
             16 RETURN_VALUE

>>> def g(): return [l for l in (locals(),)]
... 
>>> dis(g)
  1           0 LOAD_CONST               1 (<code object <listcomp> at 0x7f5b65cb8930, file "<stdin>", line 1>)
              2 LOAD_CONST               2 ('g.<locals>.<listcomp>')
              4 MAKE_FUNCTION            0
              6 LOAD_GLOBAL              0 (locals)
              8 CALL_FUNCTION            0
             10 BUILD_TUPLE              1
             12 GET_ITER
             14 CALL_FUNCTION            1
             16 RETURN_VALUE
如果您的Python版本是3.6或更新版本,则可以使用(f字符串)[

>>> def g(): return [l for l in (locals(),)]
... 
>>> dis(g)
  1           0 LOAD_CONST               1 (<code object <listcomp> at 0x7f5b65cb8930, file "<stdin>", line 1>)
              2 LOAD_CONST               2 ('g.<locals>.<listcomp>')
              4 MAKE_FUNCTION            0
              6 LOAD_GLOBAL              0 (locals)
              8 CALL_FUNCTION            0
             10 BUILD_TUPLE              1
             12 GET_ITER
             14 CALL_FUNCTION            1
             16 RETURN_VALUE
但是,我认为每次迭代都在
locals()
中查找不是一个好主意。您可以构建
格式字符串一次,并在列表中使用它:

>>> def g(): return [l for l in (locals(),)]
... 
>>> dis(g)
  1           0 LOAD_CONST               1 (<code object <listcomp> at 0x7f5b65cb8930, file "<stdin>", line 1>)
              2 LOAD_CONST               2 ('g.<locals>.<listcomp>')
              4 MAKE_FUNCTION            0
              6 LOAD_GLOBAL              0 (locals)
              8 CALL_FUNCTION            0
             10 BUILD_TUPLE              1
             12 GET_ITER
             14 CALL_FUNCTION            1
             16 RETURN_VALUE
>>> format_string = '{name_var}_{{i:02d}}of{maxpg:02d}.{date_var}'.format(**locals()) 
>>> format_string
'VAR_{i:02d}of01.2019-01-01'
或(>=3.6):

>>> def g(): return [l for l in (locals(),)]
... 
>>> dis(g)
  1           0 LOAD_CONST               1 (<code object <listcomp> at 0x7f5b65cb8930, file "<stdin>", line 1>)
              2 LOAD_CONST               2 ('g.<locals>.<listcomp>')
              4 MAKE_FUNCTION            0
              6 LOAD_GLOBAL              0 (locals)
              8 CALL_FUNCTION            0
             10 BUILD_TUPLE              1
             12 GET_ITER
             14 CALL_FUNCTION            1
             16 RETURN_VALUE
那么你有:

>>> def g(): return [l for l in (locals(),)]
... 
>>> dis(g)
  1           0 LOAD_CONST               1 (<code object <listcomp> at 0x7f5b65cb8930, file "<stdin>", line 1>)
              2 LOAD_CONST               2 ('g.<locals>.<listcomp>')
              4 MAKE_FUNCTION            0
              6 LOAD_GLOBAL              0 (locals)
              8 CALL_FUNCTION            0
             10 BUILD_TUPLE              1
             12 GET_ITER
             14 CALL_FUNCTION            1
             16 RETURN_VALUE
>>> [format_string.format(i=i) for i in range(start, end)]
['VAR_00of01.2019-01-01', 'VAR_01of01.2019-01-01', 'VAR_02of01.2019-01-01', 'VAR_03of01.2019-01-01', 'VAR_04of01.2019-01-01', 'VAR_05of01.2019-01-01', 'VAR_06of01.2019-01-01', 'VAR_07of01.2019-01-01', 'VAR_08of01.2019-01-01', 'VAR_09of01.2019-01-01']

请为我们提供一个更清楚的例子,目前您的代码可以在任何版本中工作……您是否偶然使用了一些损坏的外壳?
***
不是标准的python repl所显示的。很抱歉造成混淆。我将玩具示例修复为一个具有代表性的示例,并重新测试以确认它可以在python 2中工作,而不是在python 3中工作。旧的示例仅适用于在pdb中被破坏(由于pdb特定的原因)。在Python 3上,列表理解有自己的局部作用域。外部作用域中的变量不会显示在
locals()中
除非列表理解使用它们作为闭包变量。@bamboo77:如果列表理解包含变量
blah
的直接名称查找,类似于
[blah for thing in stuff]
,然后编译器将编译代码以完成从理解中访问
blah
所需的额外工作。如果它只调用
局部变量
,比如
[locals()['blah']for thing in stuff]
,编译器不会激活支持查找所需的机制。