2017-12-27 6 views
0

このメッセージはsonarlintからのメッセージで、この機能の認知的複雑さを軽減する方法を理解しようとしています。いかなる援助も前もって評価される。あなたは拡張子でファイルをフィルタリングするための2つのジェネレータ式を使って、インデントの1つのレベルを削除することができPythonこの機能をリファクタリングして、認知の複雑さを19から15に引き下げる

import os 
import json 
import click 
import hcl 

cfn = [".json", ".template", ".yaml", ".yml"] 
tf = ["tf"] 

def file_handler(dir): 
    for root, dirs, files in os.walk(dir): 
     for file in files: 
      if file.endswith(tuple(cfn)): 
       with open(os.path.join(root, file), 'r') as fin: 
        try: 
         file = fin.read() 
         if "AWSTemplateFormatVersion" in file: 
          data = json.dumps(file) 
          print(data) 

        except ValueError as e: 
         raise SystemExit(e) 

      elif file.endswith(tuple(tf)): 
       with open(os.path.join(root, file), 'r') as file: 
        try: 
         obj = hcl.load(file) 
         data = json.dumps(obj) 
         print(data) 
        except ValueError as e: 
         raise SystemExit(e) 
    return data 
+0

結果の数値を得るために使用しているメトリックスツールは何ですか? – SteveJ

+0

関数を抽出し、ファイルタイプのハンドラルックアップを作成し、エラー処理を統一し、重複を取り除くなど –

+1

[codereview.se]に投稿したほうがよいでしょう –

答えて

2

抽出機能:

def _file_paths(directory): 
    for root, dirs, filenames in os.walk(directory): 
     for filename in filenames: 
      file_path = os.path.join(root, filename) 
      if os.path.isfile(file_path): 
       yield file_path 

統一例外処理:

def _handle_cfn(file_object): 
    file_contents = file_object.read() 
    if "AWSTemplateFormatVersion" in file_contents: 
     data = json.dumps(file_contents) 
     print(data) 


def _handle_tf(file_object): 
    obj = hcl.load(file_oject) 
    data = json.dumps(obj) 
    print(data) 

がファイルにnullハンドラを作成します。ファイルタイプを処理するため

from contextlib import contextmanager 

@contextmanager 
def _translate_error(from_error, to_error): 
    try: 
     yield 
    except from_error as error: 
     raise to_error(error) 

抽出機能内線番号が一致しません:

def _null_handler(file_object): 
    pass 
ハンドラに

マップファイルの拡張子:あなたは、各ファイルを処理するための機能を抽出することで、さらに行くことができます

import os 
import json 
import click 
import hcl 

def file_handler(dir): 
    for file_path in _file_paths(dir): 
     base, extension = os.path.splitext(file_path) 
     handler = _extension_handlers.get(extension, _null_handler) 
     with open(file_path) as file_object: 
      with _translate_error(ValueError, SystemExit): 
       handler(file_object) 

_extension_handlers = {'.json': _handle_cfn, 
      '.template': _handle_cfn, 
      '.yaml': _handle_cfn, 
      '.yml': _handle_cfn, 
      '.tf': _handle_tf} 

がそれを一緒に置く

def _handle_file(file_path): 
    base, extension = os.path.splitext(file_path) 
    handler = _extension_handlers.get(extension, _null_handler) 
    with open(file_path) as file_object: 
     with _translate_error(ValueError, SystemExit): 
      handler(file_object) 

その後主な機能:

def file_handler(dir): 
    for file_path in _file_paths(dir): 
     _handle_file(file_path) 
+1

最後の2行目の 'file_handler'非 'マップベース'); 'map'は関数型プログラミングのためのものであり、副作用(不要な一時的な' list'sをPython 2で作成し、Python 3では何も変更せずに不必要に作成する)に使うべきではありません。 – ShadowRanger

+0

@ShadowRangerは合意したが、必要以上に説明がなくても削除される。 –

+0

これは機能しました。 DEF _file_paths(ディレクトリ):os.walkのルート、DIRS、ファイル名(ディレクトリ)のため :ファイル名でのファイル名の : パス= os.path.join(ルート、ファイル名) (os.path.isfile場合パス): yield path – kilomo

0

def file_handler(dir): 
    for root, dirs, files in os.walk(dir): 
     cfn_files = (file for file in files if file.endswith(tuple(cfn))) 
     tf_files = (file for file in files if file.endswith(tuple(tf))) 
     for file in cfn_files: 
      with open(os.path.join(root, file), 'r') as fin: 
       try: 
        file = fin.read() 
        if "AWSTemplateFormatVersion" in file: 
         data = json.dumps(file) 
         print(data) 
       except ValueError as e: 
        raise SystemExit(e) 
     for file in tf_files: 
      with open(os.path.join(root, file), 'r') as file: 
       try: 
        obj = hcl.load(file) 
        data = json.dumps(obj) 
        print(data) 
       except ValueError as e: 
        raise SystemExit(e) 
    return data 
0

をあなたはどのようなファイル拡張子にあなたを知っているときは特に見つける再帰的なファイルのglobを使用することを検討すべきです「再を探して:FYI

import glob 
import json 
import os 

import click 
import hcl 

def file_handler(dir): 
    for extension in cfn: 
     # eg: /path/to/dir/**/*.json 
     glob_search = os.path.join(dir, "**/*{}".format(extension)) 
     filenames = glob.glob(glob_search, recursive=True) 

     for filename in filenames: 
      with open(filename, 'r') as fin: 
       try: 
        file = fin.read() 
        if "AWSTemplateFormatVersion" in file: 
         data = json.dumps(file) 
         print(data) 

       except ValueError as e: 
        raise SystemExit(e) 

    for extension in tf: 
     # eg: /path/to/dir/**/*tf 
     glob_search = os.path.join(dir, "**/*{}".format(extension)) 
     filenames = glob.glob(glob_search, recursive=True) 

     for filename in filenames: 
      with open(filename, 'r') as file: 
       try: 
        obj = hcl.load(file) 
        data = json.dumps(obj) 
        print(data) 
       except ValueError as e: 
        raise SystemExit(e) 

:グロブを使用してについての質問(Use a Glob() to find files recursively in Python?

ファイルパスを生成する
関連する問題