<p>在包中以可执行文件的形式启动模块是一种不好的做法。</p>
<p>当你开发某个东西时,你要么构建一个库,这个库将被其他程序导入,因此允许直接执行它的子模块没有多大意义,要么构建一个可执行文件,在这种情况下,没有理由让它成为包的一部分。</p>
<p>这就是在<code>setup.py</code>中区分包和脚本的原因。程序包将位于<code>site-packages</code>下,而脚本将安装在<code>/usr/bin</code>(或类似的位置,具体取决于操作系统)。</p>
<p>因此,我建议使用以下布局:</p>
<pre><code>/
├── mydirectory
| ├── __init__.py
| ├── file1.py
└── file2.py
</code></pre>
<p>其中,<code>file2.py</code>将<code>file1.py</code>作为任何其他希望使用库的代码导入,<code>mydirectory</code>,并使用<em>绝对导入</em>:</p>
<pre><code>from mydirectory.file1 import f
</code></pre>
<p>当您为项目编写<code>setup.py</code>脚本时,您只需将<code>mydirectory</code>作为包和<code>file2.py</code>作为脚本列出,一切都将正常工作。不需要摆弄<code>sys.path</code>。</p>
<p>如果出于某种原因,您确实希望运行包的子模块,那么正确的方法是使用<code>-m</code>开关:</p>
<pre><code>python -m mydirectory.file1
</code></pre>
<p>这将加载整个包,然后将模块作为脚本执行,从而允许相对导入成功。</p>
<p>我个人不会这么做。也因为很多人甚至不知道你能做到这一点,最终会得到与你相同的错误,并认为包是坏的。</p>
<hr/>
<p>关于当前接受的答案,它说您应该只使用一个<em>隐式</em>相对导入<code>from file1 import f</code>,因为它将工作,因为它们在同一目录中:</p>
<p>这是错误的!</p>
<ul>
<li>它不会在python3中工作,在python3中不允许隐式相对导入,如果您碰巧安装了<code>file1</code>模块(因为它将被导入而不是您的模块!),它肯定会崩溃。</li>
<li><p>即使它起作用,<code>file1</code>也不会被视为<code>mydirectory</code>包的一部分。这个<em>可以</em>物质。</p>
<p>例如,如果<code>file1</code>使用<code>pickle</code>,则包的名称对于正确加载/卸载数据非常重要。</p></li>
</ul>