python3:os.walk出了问题

时间:2013-09-16 14:00:30

标签: python python-3.x

我有以下目录/文件设置(这是简化的):

Ce  
+---top.txt
+---X0.0        
|     |  
|     +---Y0.0  
|     |     |
|     |     +---X0.0Y0.0Z0.0.dat
|     |     +---X0.0Y0.0Z0.05.dat   
|     +---Y0.05
|           |
|           +---X0.0Y0.05Z0.0.dat
|           +---X0.0Y0.05Z0.05.dat
+---X0.05
      |  
      +---Y0.0  
      |     |
      |     +---X0.0Y0.0Z0.0.dat
      |     +---X0.0Y0.0Z0.05.dat   
      +---Y0.05
            |
            +---X0.0Y0.05Z0.0.dat
            +---X0.0Y0.05Z0.05.dat

在每个Y目录中,我需要创建一个'psub'文件,其中包含.dat文件列表附加到文件'top.txt'的副本。

我试图在python 3中使用os.walk函数执行此操作:但是我遇到两个问题:
1.新的psub文件出现在X0.0目录中 2.代码没有列出任何文件名(可能是因为它没有找到任何文件名),然后给出错误,它无法找到X0.05目录。

到目前为止,我有以下代码:

import os

with open('top.txt', 'r') as reader:
    data=reader.read()
    for root, dirs, files in os.walk('.'):
        for folder in dirs:
            os.chdir(os.path.join(root, folder))
            with open('psub', 'a') as writer:
                writer.write(data)
                for names in files:
                    if names.endswith('.dat'):
                        print('gulp <' + names + '> ', end='', file=writer)
                        print(names.rsplit('.',1)[0], end='', file=writer)
                        print('.out', file=writer)

生成的psub文件应为:

#!/bin/bash
#MOAB -l walltime=48:00:0
#MOAB -j oe
#MOAB -N GULP-job
cd "$PBS_O_WORKDIR"
module load apps/gulp
#!/bin/bash
gulp <X0.00Y0.00Z0.00.dat> X0.00Y0.00Z0.00.out
gulp <X0.00Y0.00Z0.05.dat> X0.00Y0.00Z0.05.out

其中前七行位于top.txt中。

关于我出错的地方的任何(简单)指针将非常感激。 干杯

1 个答案:

答案 0 :(得分:3)

walk旨在以递归方式遍历所有目录,因此 没有必要自己遍历所有子目录。摆脱for folder in dirs:循环。

我还建议用单个字符串格式命令替换多个print语句,如下所示:

print('gulp <{}.dat> {}.out'.format(names.rsplit('.',1)[0]), file=writer)
#or use writer.write(), to make it more transparent

您还应该重命名一些变量,以便它们更好地代表它们的用途;例如,在最后一个循环names中调用迭代变量是误导性的,因为它实际上不是名称的集合,而是单个文件名。

编辑:为避免创建额外的空文件,您需要检查目录是否需要创建文件。您可以通过遍历文件名并设置标志(如果有)是需要处理的.dat文件来执行此操作。

编辑2:保守代码,并重命名了一堆东西,所以现在它更清晰了。

这些修改的总和导致:

import os

def isDat(filename): return filename.endswith('.dat')

def hasDat(filenames): #this method checks if it contains one ending with '.dat'
    for filename in filenames:
        if isDat(filename): return true
    return false

def datFiles(filenames):
    for filename in filenames:
        if isDat(filename): yield filename

def gulpLines(filenames):
    for filename in datFiles(filenames):
        yield 'gulp <{}.dat> {}.out\n'.format(filename.rsplit('.',1)[0])

def makePsub(root, filenames, prologue):
    with os.open(os.path.join(root, 'psub'), 'a') as writer:
    #try putting 'psub.sh' instead, perhaps it is getting confused with no extension
        writer.write(prologue)
        for gulpLine in gulpLines(filenames):
            writer.write(gulpLine)


with open('top.txt') as reader:
    prologue=reader.read() #this is a much more descriptive name
#you can close it as soon as you have its contents

for root, dirs, filenames in os.walk('.'):
    if hasDat(filenames):
        makePsub(root, filenames, prologue)

Python意味着由许多小函数组成,而不是嵌套二十深的大长怪物。

此外,通过分解代码,您可以自行确定代码的哪个部分导致问题,因为您可以单独测试每个函数。如果您怀疑(例如)问题无法正确识别.dat文件,您可以自行测试isDat函数,直到您修复它为止。如果您怀疑问题是写入psub文件,则可以通过将gulpLines替换为虚拟实现(使用预定结果列表,或让用户手动执行)来检查,而不是实际生成它们。)

您可以做的另一件事是在循环中插入调试代码。例如,插入一个语句,在您(应该)写入writer之后输出data的内容,以检查您是否确实拥有了您希望拥有的内容。另一个调试选项是运行部分代码;例如,运行一个只执行walk循环的程序,或者只将data写入文件,或者只解析文件名(将写入文件的内容打印到控制台,用于检查目的)。