如何清理这个目录遍历?

huangapple go评论78阅读模式
英文:

How to clean up this directory traversal?

问题

for maps_dir in self.directories:
    for map_dir in os.listdir(maps_dir):
        if fails_check1(map_dir):
            continue
        for filename in os.listdir(os.path.join(maps_dir, map_dir)):
            if not filename.endswith(".json"):
                continue
            file_path = os.path.join(map_dir, filename)
            if os.path.isfile(file_path):
                with open(file_path, encoding="utf-8") as demo_json:
                    demo_data: Game = json.load(demo_json)
                match_id = os.path.splitext(filename)[0]
                if fails_check2(match_id):
                    continue
                self.do_stuff(demo_data, match_id)
英文:

I have the following directory structure that i want to traverse and call a function on each (loaded) file if the directories and file pass certain criteria

self.directories[0]   
│
└───maps_dir_1
│   │   file1.json
│   │   file2.txt
│   │   file3.json
│   └───subfolder1
│       │   file111.txt
│       │   file112.txt
│       │   ..
│   
└───maps_dir_1
│   │   file4.json
│   │   file5.txt
│   │   file6.json

I have a working way but it is super nested and ugly and i am sure there has to be a cleaner way, but i am unsure what it is.

for maps_dir in self.directories:
    for map_dir in os.listdir(maps_dir):
        if fails_check1(map_dir):
            continue
        for filename in os.listdir(os.path.join(maps_dir, map_dir)):
            if not filename.endswith(".json"):
                continue
            file_path = os.path.join(map_dir, filename)
            if os.path.isfile(file_path):
                with open(file_path, encoding="utf-8") as demo_json:
                    demo_data: Game = json.load(demo_json)
                match_id = os.path.splitext(filename)[0]
                if fails_check2(match_id):
                    continue
                self.do_stuff(demo_data, match_id)

答案1

得分: 1

这是一个示例。我使用:

  • pathlib.Path - 以获得更好的抽象
  • 生成器 - 以减少嵌套,并将迭代分解为概念上的部分
import json
from pathlib import Path

directories = ['some/list', 'of/directories']

# 生成器函数
def map_dirs():
    for path in directories:
        for map_dir in Path(path).iterdir():
            if check1(map_dir):
                yield map_dir

# 生成器表达式的替代方案,如果您不介意较长的行
json_files = (file for map_dir in map_dirs() for file in map_dir.glob('*.json') if check2(file.stem))

# 概念上合并为单个循环
for json_file in json_files:
    with open(json_file) as demo_json:
        demo_data = json.load(demo_json)
        do_stuff(demo_data, json_file.stem)

我使用了布尔取反的 check1()check2(),因为在肯定表达上读起来更自然,依我看来(而且更短)。

英文:

Here's an example. I use:

  • pathlib.Path - for its better abstractions
  • generators - to reduce nesting and break up the iteration into conceptual parts
import json
from pathlib import Path

directories = ['some/list', 'of/directories']

# generator function
def map_dirs():
    for path in directories:
        for map_dir in Path(path).iterdir():
            if check1(map_dir):
                yield map_dir

# generator expression alternative, if you don't mind the long line
json_files = (file for map_dir in map_dirs() for file in map_dir.glob('*.json') if check2(file.stem))

# conceptually flattented into a single loop
for json_file in json_files:
    with open(json_file) as demo_json:
        demo_data = json.load(demo_json)
        do_stuff(demo_data, json_file.stem)

I use the boolean-flipped check1() and check2() b/c expressing in the positive reads more naturally IMO (and it's shorter).

huangapple
  • 本文由 发表于 2023年5月18日 04:10:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/76275867.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定