Tim
Tim

Reputation: 2161

Any elegant way to get relative path in Python?

Say I want to delete 'Core.dll' after 'git pull', so I write a hook.

import os

dir = os.path.dirname(__file__)
try:
    os.remove(os.path.abspath(dir+os.sep+".."+os.sep+".."+os.sep+"Assets"+os.sep+"Plugins"+os.sep+"Core.dll"))

except OSError:
    pass

Say the hook path is 'E:\client\.git\hooks', the file I want to delete is in 'E:\client\Assets\Plugins\Core.dll'.

I think my way is very silly, is there any elegant way to get the relative path?

Upvotes: 4

Views: 4462

Answers (4)

Jean-François Fabre
Jean-François Fabre

Reputation: 140148

Antti's solution is the best in Python 3. For Python 2, you could use os.pardir and os.path.join:

os.path.abspath(os.path.join(d, os.pardir, os.pardir, "Assets", "Plugins", "Core.dll"))

Upvotes: 3

Using pathlib:

from pathlib import Path

(Path(__file__).absolute().parent.parent.parent/'Assets'/'Plugins'/'Core.dll').unlink()

Upvotes: 6

Yaroslav Surzhikov
Yaroslav Surzhikov

Reputation: 1608

More readable solution:

import os 
from contextlib import suppress

with suppress(OSError):
  dir = os.path.dirname(__file__)

  while '.git' in dir:
    dir = os.path.dirname(dir)

  os.remove(
    os.path.join(
      dir,
      'Assets',
      'Plugins',
      'Core.dll'
    )
  )

Upvotes: 0

Yann Vernier
Yann Vernier

Reputation: 15877

os.path.relpath would be what you asked for. You should also be using os.path.join instead of that long list of + and sep. In Python 3's pathlib, there's relative_to. It appears your code is trying to apply a relative path, not get it in relative form. In that case, joinpath and normpath or realpath might help.

Upvotes: 1

Related Questions