0
\$\begingroup\$

I have this example:

from os.path import dirname, realpath
dirname(dirname(dirname(realpath(__file__)))

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?

\$\endgroup\$

closed as off-topic by Toby Speight, Graipher, t3chb0t, Incomputable, Mast Nov 29 '17 at 9:01

This question appears to be off-topic. The users who voted to close gave this specific reason:

If this question can be reworded to fit the rules in the help center, please edit the question.

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

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)
'/aParent/templates/blog1'
>>> uppath(__file__, 2)
'/aParent/templates'
>>> uppath(__file__, 3)
'/aParent'
\$\endgroup\$

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