上移目录直到文件夹找到python

时间:2018-02-28 16:44:42

标签: python

我有一个以下格式的包:

Electricity
|___ __main__.py
|
|__ Electricity
|    |___ general_functions
|    |___ regression_calcs
|    |    |___ create_calcs.py
|    |
|    |____ run_calcs.py
|
|
|
|__ Data_Input
     |___ regression_vals
          |__ regression_vals.csv

run_calcs.py运行regression_calcs中的代码,该代码需要来自Data_Input/Regression_vals的数据。

在找到../之前,查找Data_Input(上传文件夹的次数)的数量的最pythonic方法是什么?

这是因为我现在正在运行Electricity/Electricity/run_calcs.py中的脚本(用于测试)。最终我将在Electricity/__main__.py中运行。

它将用于df = pd.read_csv(f'{filepath}Data_Input/regression_vals/regression_vals.csv') 其中filepath = '../'*n

6 个答案:

答案 0 :(得分:2)

regression_calcs中的文件内:

from os import listdir
from os.path import join, isdir, dirname, basename

filepath = None
# get parent of the .py running
par_dir = dirname(__file__)
while True:
    # get basenames of all the directories in that parent
    dirs = [basename(join(par_dir, d)) for d in listdir(par_dir) if isdir(join(par_dir, d))]
    # the parent contains desired directory
    if 'Data_Input' in dirs:
        filepath = par_dir
        break
    # back it out another parent otherwise
    par_dir = dirname(par_dir)

当然,这仅适用于您有一个'/Data_Input/'目录!

答案 1 :(得分:1)

您可以使用Unipath

path = Path("/Electricity/Data_Input/regression_vals/regression_vals.csv")
path = path.parent
path = path.parent

现在path指的是 / Electricity / Data_Input 目录。

答案 2 :(得分:1)

我最终使用的内容(avix和pstatic的答案之间的混合):

import os, unipath
def rel_location():
    """Goes up until it finds the folder 'Input_Data', then it stops
    returns '' or '../' or '../../', or ... depending on how many times it had to go up"""
    path = unipath.Path(__file__)
    num_tries = 5
    for num_up_folder in range(num_tries):
        path = path.parent
        if 'Input_Data' in os.listdir(path):
            break

    if num_tries == num_up_folder:
        raise FileNotFoundError("The directory 'Input_Data' could not be found in the 5"
                                " directories above this file's location. ")
    location = '../'* num_up_folder
    return location

答案 3 :(得分:0)

os.scandir对于这样的内容非常有用。

def find_my_cousin(me, cousin_name):
    """Find a file or directory named `cousin_name`. Start searching at `me`,
    and traverse directly up the file tree until found."""
    if not os.path.isdir(me):
        parent_folder = os.path.dirname(me)
    else:
        parent_folder = me
    folder = None

    removed = -1
    while folder != parent_folder:  # Stop if we hit the file system root
        folder = parent_folder
        removed += 1
        with os.scandir(folder) as ls:
            for f in ls:
                if f.name == cousin_name:
                    print(
                        "{} is your cousin, {} times removed, and she lives at {}"
                        "".format(f.name, removed, f.path)
                    )
                    return f.path
        parent_folder = os.path.normpath(os.path.join(folder, os.pardir))

答案 4 :(得分:0)

这是使用pathlib并直接返回所需目录的Path对象的替代实现。

from pathlib import Path

def get_path_to_rel_location(directory_to_find):
    """Goes up in directory heirarchy until it finds directory that contains 
    `directory_to_find` and returns Path object of `directory_to_find`"""
    path = Path.cwd()
    num_tries = 5
    for num_up_folder in range(num_tries):
        path = path.parent
        if path / directory_to_find in path.iterdir():
            break

    if num_tries == num_up_folder:
        raise FileNotFoundError(f"The directory {directory_to_find} could not be found in the {num_tries}"
                                f" directories above this file's location.")
    return path / directory_to_find

# Example usage
path = get_path_to_rel_location("Input_Data")

答案 5 :(得分:0)

此答案是A H答案的修改版本,只是带有Micah Culpepper的退出条件并已简化。

import os
path = os.path.dirname(os.path.abspath(__file__))

while  "Input_Data" not in os.listdir(path):
  if path == os.path.dirname(path):
    raise FileNotFoundError("could not find Input_Data")
  path = os.path.dirname(path)