I have this example:

from os.path import dirname, realpath

And the chained dirname() applications look a bit odd to me. Is there a way to improve my code? There is of course something like Better Function Composition in Python, but that seems too complicated to me.

Maybe, some solution with function composition "" would be better?

reduce(∘, [dirname] * 3)(realpath(__file__))

But that doesn't look any better.

Do you have any ideas for this concrete example?

  • 4
    \$\begingroup\$ That 'Better Function Composition in Python' is way simpler than your reduce example. \$\endgroup\$
    – Peilonrayz
    Nov 22, 2017 at 11:57
  • 2
    \$\begingroup\$ I don't see any working code to review. \$\endgroup\$ Nov 22, 2017 at 15:53

1 Answer 1


This will be short one, but as we all know, in most cases, "explicit is better than implicit".

Indeed, the second one is ugly and not easily understandable at the first sight. Doing something like this might be better:

from os.path import dirname, realpath

filepath = realpath(__file__)

dir_of_file = dirname(filepath)
parent_dir_of_file = dirname(dir_of_file)
parents_parent_dir_of_file = dirname(parent_dir_of_file)

OFC that's in no way simpler than your first solution, altough it might be clear what the end-result will look like.

More, from here:

os.path.abspath doesn't validate anything, so if we're already appending strings to __file__ there's no need to bother with dirname. Just treat __file__ as a directory and start climbing:

# climb to __file__'s parent's parent:
os.path.abspath(__file__ + "/../../")

Climbing more than two levels starts to get ridiculous.

But, since we know how many levels to climb, we could clean this up with a simple little function:

uppath = lambda _path, n: os.sep.join(_path.split(os.sep)[:-n])

# __file__ = "/aParent/templates/blog1/page.html"
>>> uppath(__file__, 1)
>>> uppath(__file__, 2)
>>> uppath(__file__, 3)

Not the answer you're looking for? Browse other questions tagged or ask your own question.