Comment

adam smith

Thanks for this post--I have been perplexed by this same issue. I did the following to make it a little more convenient to call:

I put this code into a package_home.py module:

---
import os

def get_package_home(context):
return os.path.dirname(context["__file__"])

def get_execution_path(context, filename):
return os.path.join(get_package_home(context), filename)
---

Then in my code, I just need to import it and call it like this:

---
from package_home import get_execution_path
get_execution_path(globals(), 'template.html')
---

(It doesn't look like indentation is preserved in these posts.)

Python is not my primary language, so I am not sure if this is possible, but I wonder if we can't get rid of the repetitive globals() in the call by having the get_execution_path method somehow (through introspection) get this information for the calling object.

Also, is there a way to include these methods in an upper level package's __init__.py file so they can be available to all the code in an application without having to explicitly import it into every module we want to use it in?

Replies

adam smith

OK, I finally returned to this, and here is the latest version using introspection to make finding the package home as convenient as possible:

# IN package_home.py
import os, sys, inspect

def _package_home(filename):
return os.path.dirname(filename)

def package_home(context):
""" this preserves the functionality of the original package_home function
within this new approach"""
return _package_home(context["__file__"])

def execution_path(filename):
return os.path.join(_package_home(inspect.getfile(sys._getframe(1))), filename)

def execution_path2(filename):
"""alternately, you can just use this method to hide a lot of complexity
without needing any of the other functions above"""
return os.path.join(os.path.dirname(inspect.getfile(sys._getframe(1))), filename)

#USAGE
from package_home import execution_path
execution_path('template.html')

Again, sorry that I don't know how to preserve indentation in these posts.

The sys._getframe(1) call examines the call stack and retrieves information about the calling function, so no matter how it is executed, it should work.