Relative paths in Python

前端 未结 15 1496
陌清茗
陌清茗 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 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)
    

提交回复
热议问题