Relative paths in Python

前端 未结 15 1485
陌清茗
陌清茗 2020-11-22 07:39

I\'m building a simple helper script for work that will copy a couple of template files in our code base to the current directory. I don\'t, however, have the absolute path

相关标签:
15条回答
  • 2020-11-22 07:54

    Consider my code:

    import os
    
    
    def readFile(filename):
        filehandle = open(filename)
        print filehandle.read()
        filehandle.close()
    
    
    
    fileDir = os.path.dirname(os.path.realpath('__file__'))
    print fileDir
    
    #For accessing the file in the same folder
    filename = "same.txt"
    readFile(filename)
    
    #For accessing the file in a folder contained in the current folder
    filename = os.path.join(fileDir, 'Folder1.1/same.txt')
    readFile(filename)
    
    #For accessing the file in the parent folder of the current folder
    filename = os.path.join(fileDir, '../same.txt')
    readFile(filename)
    
    #For accessing the file inside a sibling folder.
    filename = os.path.join(fileDir, '../Folder2/same.txt')
    filename = os.path.abspath(os.path.realpath(filename))
    print filename
    readFile(filename)
    
    0 讨论(0)
  • 2020-11-22 07:55

    See sys.path As initialized upon program startup, the first item of this list, path[0], is the directory containing the script that was used to invoke the Python interpreter.

    Use this path as the root folder from which you apply your relative path

    >>> import sys
    >>> import os.path
    >>> sys.path[0]
    'C:\\Python25\\Lib\\idlelib'
    >>> os.path.relpath(sys.path[0], "path_to_libs") # if you have python 2.6
    >>> os.path.join(sys.path[0], "path_to_libs")
    'C:\\Python25\\Lib\\idlelib\\path_to_libs'
    
    0 讨论(0)
  • 2020-11-22 07:56

    An alternative which works for me:

    this_dir = os.path.dirname(__file__) 
    filename = os.path.realpath("{0}/relative/file.path".format(this_dir))
    
    0 讨论(0)
  • 2020-11-22 07:57

    you need os.path.realpath (sample below adds the parent directory to your path)

    import sys,os
    sys.path.append(os.path.realpath('..'))
    
    0 讨论(0)
  • 2020-11-22 08:01

    It's 2018 now, and Python have already evolve to the __future__ long time ago. So how about using the amazing pathlib coming with Python 3.4 to accomplish the task instead of struggling with os, os.path, glob, shutil, etc.

    So we have 3 paths here (possibly duplicated):

    • mod_path: which is the path of the simple helper script
    • src_path: which contains a couple of template files waiting to be copied.
    • cwd: current directory, the destination of those template files.

    and the problem is: we don't have the full path of src_path, only know it's relative path to the mod_path.

    Now let's solve this with the the amazing pathlib:

    # Hope you don't be imprisoned by legacy Python code :)
    from pathlib import Path
    
    # `cwd`: current directory is straightforward
    cwd = Path.cwd()
    
    # `mod_path`: According to the accepted answer and combine with future power
    # if we are in the `helper_script.py`
    mod_path = Path(__file__).parent
    # OR if we are `import helper_script`
    mod_path = Path(helper_script.__file__).parent
    
    # `src_path`: with the future power, it's just so straightforward
    relative_path_1 = 'same/parent/with/helper/script/'
    relative_path_2 = '../../or/any/level/up/'
    src_path_1 = (mod_path / relative_path_1).resolve()
    src_path_2 = (mod_path / relative_path_2).resolve()
    

    In the future, it just that simple. :D


    Moreover, we can select and check and copy/move those template files with pathlib:

    if src_path != cwd:
        # When we have different types of files in the `src_path`
        for template_path in src_path.glob('*.ini'):
            fname = template_path.name
            target = cwd / fname
            if not target.exists():
                # This is the COPY action
                with target.open(mode='wb') as fd:
                    fd.write(template_path.read_bytes())
                # If we want MOVE action, we could use:
                # template_path.replace(target)
    
    0 讨论(0)
  • 2020-11-22 08:03

    What worked for me is using sys.path.insert. Then I specified the directory I needed to go. For example I just needed to go up one directory.

    import sys
    sys.path.insert(0, '../')
    
    0 讨论(0)
提交回复
热议问题