如何从目录中读取文件并将其转换为表?

时间:2018-07-11 19:57:37

标签: python operating-system

我有一个接受位置参数的类(startDateendDateunmappedDirfundCodes),我有以下方法:

下面的方法应该采用fundCodes数组,然后在目录中查找并查看是否找到符合特定格式的文件

def file_match(self, fundCodes):
    # Get a list of the files in the unmapped directory
    files = os.listdir(self.unmappedDir)

    # loop through all the files and search for matching fund code
    for check_fund in fundCodes:

        # set a file pattern
        file_match = 'unmapped_positions_{fund}_{start}_{end}.csv'.format(fund=check_fund, start=self.startDate, end=self.endDate)
        # look in the unmappeddir and see if there's a file with that name
        if file_match in files:
            # if there's a match, load unmapped positions as etl
            return self.read_file(file_match)
        else:
            Logger.error('No file found with those dates/funds')

另一个方法只是应该从该文件创建一个etl表。

def read_file(self, filename):
    loadDir = Path(self.unmappedDir)
    for file in loadDir.iterdir():
        print('*' *40)
        Logger.info("Found a file : {}".format(filename))
        print(filename)
        unmapped_positions_table = etl.fromcsv(filename)
        print(unmapped_positions_table)
        print('*' * 40)
        return unmapped_positions_table

运行它时,我可以检索文件名:

Found a file : unmapped_positions_PUPSFF_2018-07-01_2018-07-11.csv unmapped_positions_PUPSFF_2018-07-01_2018-07-11.csv

但是当尝试创建表时,出现此错误:

FileNotFoundError: [Errno 2] No such file or directory: 'unmapped_positions_PUPSFF_2018-07-01_2018-07-11.csv'

是否需要完整的文件名路径?

2 个答案:

答案 0 :(得分:0)

与此:

files = os.listdir(self.unmappedDir)

您得到self.unmappedDir

的文件名称

因此,当名称匹配时(生成名称时),您必须通过传递完整路径来读取文件 (否则例程可能会检查当前目录):

return self.read_file(os.path.join(self.unmappedDir,file_match))

在旁边:在此处使用set

files = set(os.listdir(self.unmappedDir))

因此文件名查找比使用list

快得多

您的read_file方法(我之前没有看到)应该只是打开文件,而不是再次扫描目录(无论如何都要在第一次迭代中返回,所以这没有意义):< / p>

def read_file(self, filepath):
    print('*' *40)
    Logger.info("Found a file : {}".format(filepath))
    print(filepath)
    unmapped_positions_table = etl.fromcsv(filepath)
    print(unmapped_positions_table)
    print('*' * 40)
    return unmapped_positions_table

或者,不要更改您的主要代码(set部分除外),并在目录read_file中加上目录名,因为它是一个实例方法,因此非常方便。

答案 1 :(得分:0)

最直接的问题是您需要完整的路径名。

您尝试调用Sub Equity() Dim rng As Range, rw As Range, arr, i As Long, n As Long Set rng = Range("P4:R12") ReDim arr(1 To rng.Rows.Count, 1 To rng.Columns.Count) For Each rw In rng.Rows If Application.CountA(rw) > 0 And rw.Cells(2) <> "" Then i = i + 1 For n = 1 To UBound(arr, 2) arr(i, n) = rw.Cells(n) Next n End If Next rw rng.Value = arr End Sub 的{​​{1}}被传递到函数中,并最终来自filename。这意味着它是相对于fromcsv的路径。

除非碰巧也是您当前的工作目录,否则它将不是相对于当前工作目录的有效路径。

要解决此问题,您想使用listdir(self.unmappedDir)而不是self.unmappedDir。像这样:

os.path.join(self.unmappedDir, filename)

或者,您也可以像使用filename循环那样使用pathlib对象而不是字符串。如果return self.read_file(os.path.join(self.unmappedDir), file_match) for file in loadDir.iterdir():而不是哑字符串,那么您可以将其传递给file_match,它将起作用。


但是,如果那是您真正想要的,那么您将有很多无用的代码。实际上,整个Path函数应该只是一行:

read_file

您要做的是遍历目录中的每个文件,然后忽略该文件并读取read_file,然后在第一个文件之后早返回。因此,如果那里只有1个文件,或其中有20个文件,则相当于一个文件;如果没有文件,则返回def read_file(self, path): return etl.fromcsv(path) 。无论哪种方式,除了增加复杂性,浪费的性能和多个潜在的错误之外,它都无济于事。

另一方面,如果循环 应该可以做一些有意义的事情,那么您应该在循环内部使用filename而不是None,您几乎当然不应在循环内进行无条件的file