<p><a href="http://www.python.org/dev/peps/pep-0366/">PEP 366</a>中给出的“样板文件”似乎不完整。尽管它设置了<code>__package__</code>变量,但它实际上并不导入包,这也是允许相对导入工作所必需的。<i> extraneon的解决方案是正确的。</p>
<p>注意,仅仅在<code>sys.path</code>中包含模块的目录是不够的,需要显式导入相应的包。与<a href="http://www.python.org/dev/peps/pep-0366/">PEP 366</a>中给出的示例相比,下面的示例更适合于确保无论如何调用python模块(通过规则的<code>import</code>,或通过<code>python -m</code>,或通过<code>python</code>,从任何位置调用),都可以执行python模块:</p>
<pre><code># boilerplate to allow running as script directly
if __name__ == "__main__" and __package__ is None:
import sys, os
# The following assumes the script is in the top level of the package
# directory. We use dirname() to help get the parent directory to add to
# sys.path, so that we can import the current package. This is necessary
# since when invoked directly, the 'current' package is not automatically
# imported.
parent_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(1, parent_dir)
import mypackage
__package__ = str("mypackage")
del sys, os
# now you can use relative imports here that will work regardless of how this
# python file was accessed (either through 'import', through 'python -m', or
# directly.
</code></pre>
<p>如果脚本不在包目录的顶层,并且需要导入顶层以下的模块,则必须重复<code>os.path.dirname</code>,直到<code>parent_dir</code>是包含顶层的目录为止。</p>