我有以下目录结构:
\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
现在我希望能够做类似
的事情from .extras import decorators
from decorators import benchmark
来自somethingelse.py
为了实现这个目的,我需要在哪里放置__init__.py
个文件,(此时,“\ something \ python \”路径被添加到我的.tchsrc中)
现在,我收到以下错误:
from .extras import decorators
ValueError: Attempted relative import in non-package
将它添加到我的pythonpath是一个问题吗?或者我该如何解决这个问题?我目前的解决方法是将decorators.py复制到我所创建的每个新目录中(如果我创建了我的代码的新版本,如“20131029”),但这只是一个愚蠢的解决方法,这意味着我必须使用copypaste每次我创建一个新版本的代码时都会有很多东西,所以我想要一个带有正确导入的更优雅的版本。
注意:我在python 2.7中工作,如果这有什么区别?
编辑:是的,我通过执行
来运行它python somethingelse.py
更多编辑:不知道基准装饰器的定义方式是否重要? (它不是一个类左右,接下来的东西完全来自decorators.py文件)
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
编辑:如果我把\ something \ python \ extras \放到我的pythonpath,我得
ImportError: No module named decorators
我跑的时候:
from decorators import benchmark
这是否意味着在extras-directory内部我需要创建另一个子目录,其中我比放置decorators.py?
编辑:在.tchsrc中,我添加了以下行:
setenv PYTHONPATH /bla/blabla/something/python/extras/
并在somethingelse.py中,如果我运行以下内容:
import sys
s = sys.path
for k in s:
print k
我发现路径/ bla / blabla / something / python / extras /在该列表中,所以我不明白为什么它不起作用?
答案 0 :(得分:3)
您的20131029
目录不是包,因此您不能使用相对导入路径。
您可以使用当前脚本的相对路径将extras
目录添加到Python模块搜索路径中:
import sys, os
here = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, os.path.normpath(os.path.join(here, '../extras')))
现在导入首先在extras
目录中查找模块,因此请使用:
import decorators
因为您的目录名本身仅使用数字,所以无法将包装成;包名必须遵守Python标识符规则,这些规则不能以数字开头。即使您重命名了目录并添加了__init__.py
文件,当您在目录中作为脚本运行文件时,仍然无法使用它作为包;脚本始终被认为是在包之外生活。你必须有一个顶级的“垫片”脚本,它从包中导入实际代码:
from package_20131029.somethingelse import main
main()