python中的此函数将文件下载到AWS S3存储桶。我有一个代码问题,我不想嵌套三个“如果”,以便代码可以更清晰和可读:
for fileinfo in response['Contents']:
if key in fileinfo['Key']:
if '/' in fileinfo['Key']:
filekeysplit = fileinfo['Key'].rsplit('/', 1)
if filekeysplit[1] == '':
continue
if not os.path.exists(file):
os.makedirs(file)
fileout = os.path.join(file, filekeysplit[1])
self._s3.download_file(bucket, fileinfo['Key'], fileout)
else:
self._s3.download_file(bucket, fileinfo['Key'], file)
怎么做?谢谢
答案 0 :(得分:1)
您始终可以反转测试并使用continue
跳过迭代:
for fileinfo in response['Contents']:
if key not in fileinfo['Key']:
continue
if '/' not in fileinfo['Key']:
self._s3.download_file(bucket, fileinfo['Key'], file)
continue
filekeysplit = fileinfo['Key'].rsplit('/', 1)
if filekeysplit[1] == '':
continue
if not os.path.exists(file):
os.makedirs(file)
fileout = os.path.join(file, filekeysplit[1])
self._s3.download_file(bucket, fileinfo['Key'], fileout)
我们可以提出双download_file()
次电话;跳过以/
提前结尾的密钥。您只需要在循环外创建目录一次(我也在这里将file
重命名为directory
)。我在这里使用str.rpartition()
而不是str.rsplit()
:
# file has been renamed to directory, no need to test,
# as `os.makedirs()` does this for us
os.makedirs(directory)
for fileinfo in response['Contents']:
if key not in fileinfo['Key']:
continue
__, slash, basename = fileinfo['Key'].rpartition('/')
if not basename and slash: # ended in "/"
continue
target = directory
if slash: # there was a partition
target = os.path.join(target, basename)
self._s3.download_file(bucket, fileinfo['Key'], target)
答案 1 :(得分:1)
我想建议使用标准库的一些功能。就像Martijn Pieters所说的那样,你应该将你的file
变量重命名为target_directory
或类似的东西,因为如果你不这样做,它可能会使你的代码的读者感到困惑:
for fileinfo in response['Contents']:
filepath_retrieved = fileinfo['Key']
if key in filepath_retrieved:
pathname_retrieved, filename_retrieved = os.path.split(filepath_retrieved)
if pathname_retrieved:
if filename_retrieved:
os.makedirs(target_directory, exist_ok=True)
output_filepath = os.path.join(target_directory, filename_retrieved)
self._s3.download_file(bucket, filepath_retrieved, output_filepath)
else:
output_filepath = target_directory
self._s3.download_file(bucket, filepath_retrieved, output_filepath)
使用的功能是:
os.path.split()
而不是str.rsplit()或str.rpartition(),因为当您尝试执行fileinfo['Key'].rsplit('/', 1)
exist_ok
os.makedirs()
的参数,因此在您需要创建目录之前,不必担心目录的存在。