我从sonarlint看到这条消息并试图弄清楚如何降低此功能的认知复杂性。任何帮助都会提前得到赞赏。
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 :(得分: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
统一异常处理:
from contextlib import contextmanager
@contextmanager
def _translate_error(from_error, to_error):
try:
yield
except from_error as error:
raise to_error(error)
提取函数以处理文件类型:
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)
为文件扩展名不匹配时创建一个空处理程序:
def _null_handler(file_object):
pass
将文件扩展名映射到处理程序:
_extension_handlers = {'.json': _handle_cfn,
'.template': _handle_cfn,
'.yaml': _handle_cfn,
'.yml': _handle_cfn,
'.tf': _handle_tf}
把它放在一起:
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)
您可以通过提取处理每个文件的函数来进一步:
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 :(得分: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
答案 2 :(得分:0)
您应该考虑使用glob
进行递归文件查找,尤其是当您知道要查找的文件扩展名时:
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)
仅供参考:关于使用glob(Use a Glob() to find files recursively in Python?)
的问题