Python 在第一个文件之外的循环中找不到文件

Python not finding files in loop beyond the first file

提问人:grimbar 提问时间:10/11/2023 最后编辑:grimbar 更新时间:10/12/2023 访问量:67

问:

我有一个脚本,其中包含对目录中文件的 for 循环。脚本和目录都放在我机器上的同一目录中。目录名称作为参数传递给脚本。

我打开每个文件(yml),将内容读取到字典中,然后使用文件的所述字典的内容从我的代码中调用一个方法。第一个循环(在第一个文件上)运行没有错误,但在第二个循环中,python 会抛出打开文件的行。"FileNotFoundError: [Errno 2] No such file or directory"

config_dir = args.param # this is the directory which contains the yml files
config_file_names = os.listdir(config_dir)  # this is a list of said files

    for config_file_name in config_file_names:
        config_file_path = os.path.join(config_dir, config_file_name) # here the current file is concatenated with the directory to form a path from the working directory of script to the file
        with open(config_file_path) as f:  # LINE OF ERROR IN SECOND LOOP
            print(config_file_path)
            config = yaml.load(f, Loader=SafeLoader)
        --------------- MORE CODE ---------------

我认为这是在建造路径时的一个错误。 然而,这并没有改变任何事情:

config_file_path = config_dir + "/" + config_file_name

如果我在上面显示的代码之后添加一个继续,但在我省略的其余代码之前,代码运行没有错误:

parser = argparse.ArgumentParser()

parser.add_argument("-p", "--param", help="Path to parameter file directory", required=True)

args = parser.parse_args()

config_dir = args.param # this is the directory which contains the yml files
config_file_names = os.listdir(config_dir)  # this is a list of said files

    for config_file_name in config_file_names:
        config_file_path = os.path.join(config_dir, config_file_name) # here the current file is concatenated with the directory to form a path from the working directory of script to the file
        with open(config_file_path) as f:
            print(config_file_path)
            config = yaml.load(f, Loader=SafeLoader)
            continue # this fixes it
        --------------- MORE CODE ---------------

这将生成以下控制台输出:

C:\Users\user\mambaforge\envs\traintool\python.exe C:\Users\user\PycharmProjects\traintool\src\multiple_runs.py -p opt_configs 
2023-10-11 14:16:05.419007: I tensorflow/core/platform/cpu_feature_guard.cc:193] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations:  AVX AVX2
To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.
1 Physical GPUs, 1 Logical GPUs
opt_configs\config_alpha_proteo_class.yml
2023-10-11 14:16:06.069136: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1616] Created device /job:localhost/replica:0/task:0/device:GPU:0 with 5987 MB memory:  -> device: 0, name: NVIDIA GeForce RTX 2070, pci bus id: 0000:01:00.0, compute capability: 7.5
opt_configs\config_amp_class.yml
opt_configs\config_biofilm_class.yml
opt_configs\config_cytotoxic_class.yml
opt_configs\config_proteo_class.yml
opt_configs\config_pseudo_biofilm_class.yml
opt_configs\config_p_aeruginosa_class.yml

Process finished with exit code 0

不要介意 tensorflow 的细节,这些总是由这个特定的第三方包打印的。

这表明下面的代码是原因。但根据 pycharms Search for Usage 函数,这些是唯一读取或写入相关元素的行,它们是:config_dir、config_file_names、config_file_name config_file_path

在我的整个项目中,我没有改变这些元素。我不知道有什么东西可能会影响这些文件的迭代。 我尝试删除第一个文件。错误将发生在第三个文件(在这种情况下,它当然是第二个文件)。 我无法使用示例代码在我的程序之外重现错误。

这个项目的代码分布在多个脚本中,因此共享整个脚本是不可行的。我只使用 yaml 加载器创建的字典内容。我希望有人可能知道任何事情都会真正影响一个接一个地阅读文件。我在两台机器(家用 PC 和 Servercluster)上尝试过,没有区别。

Python 3.9.13 中文文档

编辑: 以下是脚本文件的其余部分:

import argparse
import yaml
from yaml.loader import SafeLoader
import os

def main():
    parser = argparse.ArgumentParser()

    parser.add_argument("-p", "--param", help="Path to parameter file directory", required=True)

    args = parser.parse_args()

    config_dir = args.param
    config_file_names = os.listdir(config_dir)

    for config_file_name in config_file_names:
        config_file_path = os.path.join(config_dir, config_file_name)
        with open(config_file_path) as f:
            print(config_file_path)
            config = yaml.load(f, Loader=SafeLoader)
        continue

        assert config["modus"] == "train" or config["modus"] == "selection", (
            "Illegal Argument." "modus must be either train or selection."
        )

        if config["modus"] == "train":
            for model in config["model"]:
                for loss in config["loss"]:
                    for optimizer in config["optimizer"]:
                        train.train_seq(
                            trainfile=config["train_file"],
                            lr=config["learning_rate"],
                            epochs=config["epochs"],
                            batch_size=config["batch_size"],
                            loss=loss,
                            optimizer=optimizer,
                            model_name=model,
                            encoding=config["encoding"],
                            patience=config["patience"],
                            cv_split=config["cv_split"],
                            val_files=config["val_file"],
                            test_size=config["test_size"],
                            early_stopping=config["early_stopping"],
                            monitor=config["monitor"],
                            shuffle=config["shuffle"],
                            validation_split=config["validation_split"],
                            x_values=config["x_values"],
                            y_values=config["y_values"],
                            regression=config["regression"],
                            momentum=config["momentum"],
                            sep=config["sep"]
                        )
        elif config["modus"] == "selection":
            utils.find_best_model(config["path_to_models"], config["selection_criterion"])


if __name__ == "__main__":
    import utils
    utils.enable_gpu_mem_growth()
    import train
    main()

据我所知,所有内容都来自dict配置中的文件内容。

python 文件 for-loop 解析 io

评论

3赞 Guy 10/11/2023
在您正在做一些影响文件的事情时,通过跳过该代码来防止这种情况。MORE CODEcontinue
0赞 grimbar 10/11/2023
在不触及包括文件在内的相关元素的情况下,我可以做什么?
2赞 Guy 10/11/2023
这不是任何人在不看到代码的情况下都可以回答的问题。
0赞 grimbar 10/12/2023
我添加了文件的其余部分。调用的方法在单独调用时会执行应有的操作,尤其是对于循环中的第一个文件,但我不知道原始配置文件有任何更改。

答:

0赞 grimbar 10/12/2023 #1

在项目深处的某个地方,工作目录发生了变化。当然,当仅发布上述脚本的部分时,这是不可见的。

我通过进行此更改解决了该问题:

base_dir = os.getcwd()

for config_file_name in config_file_names:
    os.chdir(base_dir)

这会将工作目录重置为循环之前的原始目录。 我通过在循环中获取工作目录并在调试器中显示它来找到它。 如果您遇到相同的情况,请在项目中搜索 、 或 。这些可能会引导您找到原因。IMO 更改工作目录是不好的做法,我的问题是我为什么这么想的例子。import osos.chdiros.getcwd