Reputation: 2309
I have the following directory structure:
\something\python\
extras\
__init__.py # empty file
decorators.py # contains a benchmark decorator (and other things)
20131029\ # not a package, this contains the scripts i use directly by doing "python somethingelse.py"
somethingelse.py
And now I want to be able to do something like
from .extras import decorators
from decorators import benchmark
from inside somethingelse.py
For this to work, where do I need to place __init__.py
files, (at the moment, the "\something\python\" path is added to my .tchsrc )
Now, i get the following error:
from .extras import decorators
ValueError: Attempted relative import in non-package
Is this a problem with adding it to my pythonpath? or how should I solve this? The current workaround I have is to just copypaste the decorators.py into each new directory i make (if I make a new version of my code, like the "20131029"), but that is just a stupid workaround which means I have to copypaste a lot of stuff each time i make a new version of my code, so a more elegant version with the correct imports is what I want.
Note: I am working in python 2.7, if that makes any difference?
edit: yes, i run it by doing
python somethingelse.py
more edit: no idea if the way that the benchmark decorator is defined matters? (it is not a class or so, the next thing comes exactly out of the decorators.py file)
import time, functools
def benchmark(func):
"""
A decorator that prints the time a function takes
to execute.
"""
@functools.wraps(func)
def wrapper(*args, **kwargs):
t = time.time()
res = func(*args, **kwargs)
print func.__name__, time.time()-t
return res
return wrapper
Edit: if i put the \something\python\extras\ to my pythonpath, i get
ImportError: No module named decorators
when i run:
from decorators import benchmark
Does this mean that inside that extras-directory i need to make another subdirectory, in which i than put the decorators.py?
edit: in the .tchsrc, i added the following line:
setenv PYTHONPATH /bla/blabla/something/python/extras/
and in the somethingelse.py, if i run the following:
import sys
s = sys.path
for k in s:
print k
i find that the path /bla/blabla/something/python/extras/ is in that list, so i do not get why it does not work?
Upvotes: 0
Views: 6737
Reputation: 1121486
Your 20131029
directory is not a package, so you cannot use relative import paths beyond it.
You could add the extras
directory to your Python module search path, using a relative path from your current script:
import sys, os
here = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, os.path.normpath(os.path.join(here, '../extras')))
Now imports look for modules in the extras
directory first, so use:
import decorators
Because your directory name itself is using only digits, you cannot make that a package anyway; package names must stick to Python identifier rules, which cannot start with a digit. Even if you renamed the directory, and added a __init__.py
file, you still cannot use it is as package when you run a file within the directory as a script; scripts are always considered to live outside a package. You'd have to have a top-level 'shim' script that imports the real code from a package:
from package_20131029.somethingelse import main
main()
Upvotes: 3