python3 : having problems with os. 步行

标签 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、X0.0目录下出现新的psub文件
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中。

任何关于我哪里出错的(简单的)指示将不胜感激。 干杯

最佳答案

walk 旨在自行递归地迭代所有目录,因此 无需自己遍历所有子目录。摆脱 for folder in dirs: 循环。

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

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 后插入一条输出 writer 内容的语句,以检查您是否确实拥有您期望的内容。另一个调试选项是运行部分代码;例如,运行一个仅执行 walk 循环的程序,或仅将数据写入文件,或仅解析文件名(打印它写入文件的内容)控制台,用于检查目的)。

关于python3 : having problems with os. 步行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18829936/

相关文章:

python - python 真实内存与分析内存

python - Splinter:获取不是唯一元素的 XPATH 文本片段

python - 转换时间戳格式时出现问题

php - 请求库 : Failed to establish a new connection: [Errno 13] Permission denied

python-3.x - Python-使用for循环或while循环查找列表中的最大数字

python - 使用生成器编写文件头和文件体是pythonic吗?

python - 将预测结果合并到原始数据帧?

Python N_gram 频率计数

python - 根据标点符号区分文本大小写

python - 我如何检查 Django 中是否存在用户名和电子邮件