Python 3.5.2:“名称未定义”如果目录不为空

问题描述:

我被Python 3.5.2中的一些奇怪行为卡住了。我有一个类Foo,并且想要为所有实例仅执行一段代码一次。此代码直接放在class声明的下方。Python 3.5.2:“名称未定义”如果目录不为空

import os 

class Foo: 

    path = "annotations/" 
    files = [f for f in os.listdir(path) if os.path.isfile(os.path.join(path, f))] 

    def __init__(self, x): 
     # do something 
     1+1 

当乳宁此代码,如果annotations目录是不是空(一个空文件就足够了)

Traceback (most recent call last): 
    File "foo.py", line 3, in <module> 
    class Foo: File "foo.py", line 6, in Foo 
    files = [f for f in os.listdir(path) if os.path.isfile(os.path.join(path, f))] File "foo.py", line 6, in <listcomp> 
    files = [f for f in os.listdir(path) if os.path.isfile(os.path.join(path, f))] 
NameError: name 'path' is not defined 

然而,如果annotations/是空的未发生错误出现以下错误消息。为什么?这种奇怪的行为只发生在使用单行for循环时。

我使用Python 3.5.2。当用Python 2.7.12运行上面的代码时,错误不会出现。

+0

无法在MacOs Python 3.5.2上重现。无论如何,我会建议在一个函数中计算'files'的值,而不是在'class'定义的内部 - 你所做的很丑。尝试更新/重新安装Python。 – warvariuc

+0

我使用Python 3.5.2。在Ubuntu 16.04系统上。这似乎是我向一个类添加静态代码的正常方法。为什么这应该是丑陋的?如果没有人提出令人满意的解决方案,我可能会尝试重新安装Python。 – null

+1

由于在列表理解*的嵌套范围内,您将得到'NameError',名称'path'不可见。但是只能在'if'语句中使用,而不是最外面的'for'可迭代源(因为它是在列表理解之外计算的),而'if'语句只有在迭代器中有实际元素需要测试时才会使用。看到重复。 –

如果我明白了,首先您没有“注释”路径,那么您可以制作“注释”路径并运行。如果是这样,这是有道理的,因为脚本尝试阅读“注释”路径,但路径不存在!

你可以做这样的事情:

if os.path.exists('annotations/'): 
    files = [f for f in os.listdir(path) if os.path.isfile(os.path.join(path, f))] 

,或者强制令的路径:

if not os.path.exists('annotations/'): 
    os.mkdir('annotations/') 
files = [f for f in os.listdir(path) if os.path.isfile(os.path.join(path, f))] 
+0

这不是问题。该目录存在。看到我上面的编辑 – null

如果你有路径定义,没有办法,你可以得到NameError - 你所提到的一个。 运行它可能会给你:

OSError: [Errno 2] No such file or directory: 'annotations/'

如果没有命名annotations


用于处理此类情况的任何目录 - 如果它不存在(如雨果提到你必须创建目录):

import os 

class Foo: 

    path = "annotations/" 
    if not os.path.exists('annotations/'): 
     os.mkdir('annotations/') 
    files = [f for f in os.listdir(path) if os.path.isfile(os.path.join(path, f))] 

    def __init__(self, x): 
     # do something 
     1+1 


if __name__ == "__main__": 
    obj = Foo(1) 
    print 'hello' 

输出 - 工作绝对没问题即还创建了注释目录ectory本身:

[[email protected] so_tmp]$ ls 
[[email protected] so_tmp]$ python ../path_issue.py 
hello 
[[email protected] so_tmp]$ ls 
annotations 
[[email protected] so_tmp]$ 
+0

我得到一个NameError。我不知道为什么会发生这种事情。这只有在目标目录不为空时才会发生(请参阅上面的编辑)。 – null