在Python中从相对路径导入

161 投票
7 回答
285946 浏览
提问于 2025-04-17 02:47

我有一个文件夹专门放客户代码,一个文件夹放服务器代码,还有一个文件夹放它们之间共享的代码。

Proj/
    Client/
        Client.py
    Server/
        Server.py
    Common/
        __init__.py
        Common.py

我该怎么从Server.py和Client.py中导入Common.py呢?

7 个回答

11

不要使用相对导入。

根据 PEP8 的规定:

在包内部进行相对导入是非常不推荐的。

把你所有的代码放在一个超级包里(比如叫“myapp”),然后用子包来分别处理客户端、服务器和公共代码。

更新: "Python 2.6 和 3.x 支持正确的相对导入 (...)"。想了解更多细节,可以查看 Dave 的回答

12

有趣的是,我最近也遇到了同样的问题,我是这样解决的:

结合使用Linux命令ln,我们可以让事情变得简单很多:

1. cd Proj/Client
2. ln -s ../Common ./

3. cd Proj/Server
4. ln -s ../Common ./

现在,如果你想从文件Proj/Common/Common.py导入some_stuff到你的文件Proj/Client/Client.py,只需要这样做:

# in Proj/Client/Client.py
from Common.Common import some_stuff

同样的方式也适用于Proj/Server,对于setup.py的过程也有效,这里讨论了同样的问题,希望对你有帮助!

219

编辑于2014年11月(3年后):

Python 2.6和3.x支持正确的相对导入,这样你就可以避免使用一些奇怪的方法。通过这种方式,你可以明确知道你是在进行相对导入,而不是绝对导入。这里的'..'表示去上一级目录:

from ..Common import Common

需要注意的是,这种方法只有在你从包的外部以模块的方式运行你的Python时才有效。例如:

python -m Proj

最初的奇怪方法

这种方法在某些情况下仍然很常用,尤其是当你并没有真正“安装”你的包时。例如,Django用户就很喜欢这种方法。

你可以把Common/添加到你的sys.path中(这是Python用来查找导入内容的路径列表):

import sys, os
sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'Common'))
import Common

os.path.dirname(__file__)会给你当前Python文件所在的目录,然后我们导航到'Common/'这个目录并导入'Common'这个模块。

撰写回答