获取python中子进程创建的文件列表

Get list of files created by subprocess in python

我正在运行几个不同的Unix命令,作为来自python的子进程(使用python的子进程模块),它生成将在稍后的管道中使用的文件。我想知道是否有一种优雅的方法来获取这些子流程生成的文件列表。目前我只是在使用这样的工具:

1
2
3
4
self.fastQFiles = []
for filename in os.listdir(self.workdir):
    if re.search(r'\.fastq$', filename, re.IGNORECASE):
        self.fastQFiles.append(self.workdir +"/" + filename)

搜索工作目录中的所有文件,只返回与给定扩展名匹配的文件。如果这是唯一能让我的regex变得更复杂和匹配所有期望的文件类型的方法,但是我有点担心匹配的旧文件也会出现在搜索中,我想我也可以添加一个datetime组件,但这感觉很笨拙。

是否有更清晰的方法返回由子进程生成的文件名?

编辑:再考虑一下这个问题,我能想到的最优雅的解决方案是通过集合减法来实现这一点。

1
2
3
4
preCounter = Counter(os.listdir('/directory'))
subprocess.(processArguments)
postCounter = Counter(os.listdir('/directory'))
newFiles = list(postCounter - preCounter)

如果有更好的方法,我仍然愿意接受建议。


好吧,我提出的解决方案使用了@hughdbrown结合os.stat()创建的dictDiffer类。我使用os.stat()获取st_mTime属性,该属性是上次修改文件时的属性,可以用来显示文件是否已从一个时间点覆盖到另一个时间点。我把所有的东西都存储在字典中,文件名作为关键字,在st_mtime作为值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import os
workdir = '/path/to/directory'    
preFileStats = {}
for filename in os.listdir(workdir):
    preFileStats[filename] = os.stat(workdir +"/" + filename).st_mtime

subprocess.(processArguments)

postFileStats = {}
for filename in os.listdir(workdir):
    postFileStats[filename] = os.stat(workdir +"/" + filename).st_mtime

class DictDiffer(object):
   """
    Calculate the difference between two dictionaries as:
    (1) items added
    (2) items removed
    (3) keys same in both but changed values
    (4) keys same in both and unchanged values
   """

    def __init__(self, current_dict, past_dict):
        self.current_dict, self.past_dict = current_dict, past_dict
        self.set_current, self.set_past = set(current_dict.keys()), set(past_dict.keys())
        self.intersect = self.set_current.intersection(self.set_past)
    def added(self):
        return self.set_current - self.intersect
    def removed(self):
        return self.set_past - self.intersect
    def changed(self):
        return set(o for o in self.intersect if self.past_dict[o] != self.current_dict[o])
    def unchanged(self):
        return set(o for o in self.intersect if self.past_dict[o] == self.current_dict[o])

d = DictDiffer(postFileStats, preFileStats)
newFiles = list(d.changed()) + list(d.added())

当然,dictdiffer类非常强大,可以用于检查删除的文件或未更改的文件。


我个人更喜欢简单的表达方式。易于维护。如果你想炫耀,你也可以这样做:

1
self.fastQFiles = [ff for ff in os.listdir(self.workdir) if re.search(r'\.fastq$', ff, re.IGNORECASE)]

1
self.fastQFiles = filter(lambda ff: re.search(r'\.fastq$', ff, re.IGNORECASE), os.listdir(self.workdir)

或者使用旧的好的glob.glob()

或者您可以切换到使用apply_async()并使您的函数返回它们创建的文件名。然后您就可以简单地得到这样一个列表,而不需要任何后期处理。