我有一个接受位置参数的类(startDate
,endDate
,unmappedDir
和fundCodes
),我有以下方法:
下面的方法应该采用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'
是否需要完整的文件名路径?
答案 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
。