首页 > 解决方案 > python中的相对地址

问题描述

参考这里的问题Python 中的相对路径。我有类似的问题。

我的项目结构:

proj
 |
 |--config
 |    |--ENV
 |
 |--folder1
 |    |--UI
 |       |--test2.py 
 |
 |--test1.py

我想使用 test1.py 和 test2.py 访问 ENV 文件,但我要使用相对地址,这样我每次移动项目时都不必更改代码。

import inspect
import os
dirname = os.path.dirname(os.path.abspath(inspect.stack()[0][1]))
filename = os.path.join(dirname, 'config/ENV')

上面的代码在 test1.py 处工作正常,但在 test2.py 处失败,因为现在dirname已更改。

我正在寻找可以在两个文件上使用的代码。目前我只有一个想法是在\查找proj和附加的基础上拆分地址config/ENV有没有更好更干净的方法来做到这一点?

C:\Users\User1\proj\config/ENV  -- at test1.py

C:\Users\User1\proj\folder1\UI\config/ENV  --  at test2.py

我目前的解决方案:

dirname = os.path.dirname(__file__)
PROJECT_NAME = "proj"
x = dirname[:dirname.find(PROJECT_NAME) + len(PROJECT_NAME)]
filename = os.path.join(x, 'config/ENV')

标签: pythonpython-3.x

解决方案


My Project
    some_file.py

    Resources
        bg.png
        music.mp3

    Folder
        another_file.py

如果您想从some_file.py访问您的资源,则相对路径将是./Resources/...,但如果您想使用another_file.py中的资源,您会这样做../Resources/...

因此,在您的情况下,如果您想从test1.py访问ENV文件,它的相对位置将是,但如果您想从test2.py访问它,它的相对位置将是。./config/ENV../../config/ENV

记住 ../意味着上升一个级别,./意味着同一级别。

编辑:
这里有固定路径config/ENV。传递该固定路径relative_path()会为您提供相对路径地址。

# proj
#   config
#     ENV
#
#   folder1
#     config
#       some_other_file.txt
#
#     UI
#       test2.py
# 
#   test1.py


import os

def relative_path(path):
    # Get the parent directory of the
    # file that you need the relative
    # path for.
    my_dir = path.split('/')[0]
    
    # Recursively match the directory
    # in the given path. if the match
    # not found go up one level.
    def match_dir(c_path):
        c_path = os.path.split(c_path)[0]
        
        if my_dir in os.listdir(c_path) and (
            os.path.isfile(
                os.path.join(c_path, path)
            )
        ):
            # this whole if-block can be omitted
            # if the folder you're trying to access
            # is on the same level, this just prepends
            # with './'. I added this just for
            # aesthetic reason.
            if os.path.basename(__file__) in os.listdir(c_path):
                return './' + path
                
            return path
            
        return "../" + match_dir(c_path)
    
    
    return match_dir(
        os.path.realpath(__file__)
    )


# Getting relative path from test2.py
print(relative_path("config/ENV"))
print(relative_path("config/some_other_file.txt"))

# Try running this from test1.py
print(relative_path("config/ENV")) # './config/ENV'

这不是很优化。只是一个大概的想法。


推荐阅读