NameError: global name is not defined in genexpr in python

NameError: global name is not defined in genexpr in python

这个:

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

失败:

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 list comprehensions would work - 但是理解变量会泄漏到 class 范围 - 所以这会泄漏 x:

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

所以我选择了:

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