2016-12-26 26 views
-1

python中的此函数将文件下载到AWS S3存储桶。我有,我想不是窝三个“如果”,这样的代码可以更清晰可读的代码有问题:如何重构此代码以便嵌套不超过3个“if”

  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)重复的'self._s3.download_file'也应该固定好...... 2)日志应该建立在工作功能之上......不要混合它。 –

+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()通话;跳过以/结束的密钥。你只需要创建目录一次,在循环之外(我会在这里重命名filedirectory)。我会用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) 
+0

有一个问题,你忘了在条件'if filekeysplit [1] ==''之前计算'filekeysplit'的值:' – JavaQueen

+0

@Cloudgls:谢谢,我正在重写一些内容,忘记重新写入。另一个更新即将到来。 –

1

我想使用标准库的一些特征建议。像马亭皮特斯说,你应该重新命名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)说法os.makedirs()
  • exist_ok所以你不”在你需要创建它之前,不必担心目录的存在。