名称错误:在python的genexpr中未定义全局名称

NameError: global name is not defined in genexpr in python

这是:

1
2
3
4
5
6
7
8
9
10
import os

class A(object):

    os_sep = os.sep
    _silentSkipsStart = {u'a dir%s' % os_sep}

    def _refreshBasic(self,os_sep=os_sep, skips_start=tuple(
                x.replace(os_sep, u'') for x in _silentSkipsStart)):
        pass

失败:

1
2
3
4
5
6
7
8
Traceback (most recent call last):
  File"C:/Users/MrD/.PyCharm50/config/scratches/scratch", line 3, in <module>
    class A(object):
  File"C:/Users/MrD/.PyCharm50/config/scratches/scratch", line 9, in A
    x.replace(os_sep, u'') for x in _silentSkipsStart)):
  File"C:/Users/MrD/.PyCharm50/config/scratches/scratch", line 9, in <genexpr>
    x.replace(os_sep, u'') for x in _silentSkipsStart)):
NameError: global name 'os_sep' is not defined

我想,把os_sep = os.sep带到全球范围应该可以解决这个问题(从设计的角度来看,我可能应该解决这个问题),但这里我没有得到python范围规则:为什么在其他情况下os_sep可以解决,而不是在genexpr中?


以及@padraiccunningham在评论中链接的答案:

The scope of names defined in a class block is limited to the class block; it does not extend to the code blocks of methods – this includes comprehensions and generator expressions since they are implemented using a function scope

对于python 3——对于python 2来说,列表理解是可行的——但是理解变量会泄漏到类范围——所以这会泄漏x:

1
2
3
    def _refreshBasic(self,os_sep=os_sep, skips_start=tuple(
                [x.replace(os_sep, u'') for x in _silentSkipsStart])):
        pass

所以我一起去:

1
2
3
4
5
6
7
8
9
import os

os_sep = os.sep
class A(object):
    _silentSkipsStart = {u'a dir%s' % os_sep}

    def _refreshBasic(self,os_sep=os_sep, skips_start=tuple(
                x.replace(os_sep, u'') for x in _silentSkipsStart)):
        pass