2016-12-26 18 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) 

それを行う方法:私は、私がいない巣3つのコードがより明確で読みやすいことができるように「もし」にするコードに問題がありますか?あなたはいつもテストを反転し、反復をスキップするcontinueを使用することができますあなたの

+0

1)複製された 'self._s3.download_file'も同様に修正する必要があります... 2)ロギングは、機能性の上に構築する必要があります...混在させないでください。 –

+0

'/'で終わるキーは無効で、スキップする必要がありますか? –

答えて

1

に感謝:

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()コールを引き出すことができます。 /で終了するキーをスキップします。ディレクトリを1度だけというループの外側に作成する必要があります(fileからdirectoryにも名前を変更します)。私はstr.rsplit()の代わりに、ここでstr.rpartition()を使用したい:

# 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

問題があります。あなたが 'filekeysplit [1] == ''の条件の前に' filekeysplit'の値を計算していないのを忘れてしまったのですが: – JavaQueen

+0

@Cloudgls:ありがとう、私はもう少し書き直していました。もう一つのアップデートが来ている。 –

1

私は標準ライブラリの一部の機能を使用することをお勧めしたいと思います。マルタインピータースが言ったようにあなたがいない場合、それはあなたのコードの読者を混乱させる可能性があるため、あなたがそのようなtarget_directoryか何かにあなたのfile変数の名前を変更しておく必要があります使用

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) 

機能がある:

    代わりにstr.rsplitの
  • os.path.split()()またはstr.rpartition()それはあなたがos.makedirs()fileinfo['Key'].rsplit('/', 1)
  • exist_ok議論を行うことを試みたときに、ファイルパスの末尾にファイル名を取得したかったようなので、あなたが「ドン見えるのであなたがそれを作成する必要がある前にディレクトリの存在を心配する必要はありません。
関連する問題