0

我有以下目录结构:

\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”),但这只是一个愚蠢的解决方法,这意味着我必须复制粘贴每次我制作我的代码的新版本时都会有很多东西,所以我想要一个更优雅的带有正确导入的版本。

注意:我正在使用 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

这是否意味着在那个额外目录中我需要创建另一个子目录,而不是在其中放置 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/ 在该列表中,所以我不明白为什么它不起作用?

4

1 回答 1

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文件,当您将目录中的文件作为脚本运行时,您仍然不能将其作为包使用;脚本总是被认为存在于包之外。你必须有一个从包中导入真实代码的顶级“shim”脚本:

from package_20131029.somethingelse import main

main()
于 2013-11-05T13:22:45.920 回答