it-swarm.cn

从Python中的相对路径导入

我有一个用于我的客户端代码的文件夹,一个用于我的服务器代码的文件夹,以及一个用于它们之间共享的代码的文件夹

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

如何从Server.py和Client.py导入Common.py?

76
Drew

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

Python 2.6和3.x支持正确的相对导入,你可以避免做任何hacky。使用此方法,您知道您正在获得 relative import而不是 absolute import。 '..'表示,转到我上面的目录:

from ..Common import Common

作为一个警告,只有从包中的 outside 运行python作为模块时,这才有效。例如:

python -m Proj

原来的hacky方式

在某些情况下,此方法仍然常用,您实际上并未“安装”您的软件包。例如,它受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'模块。

116
Dave

不做相对导入。

来自 PEP8

不鼓励进行包装内进口的相对进口。

将所有代码放入一个超级包(即“myapp”)中,并使用子包作为客户端,服务器和公共代码。

更新: Python 2.6和3.x支持正确的相对导入(...)”。请参阅 戴夫的答案 了解更多详情。

14
Michał Šrajer

有趣的是,我遇到了同样的问题,我按照以下方式完成了这项工作:

结合linux命令ln,我们可以让事情变得简单:

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

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

而且,现在如果你想将some_stuff从文件:Proj/Common/Common.py导入你的文件:Proj/Client/Client.py,就像这样:

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

并且,同样适用于Proj/Server,也适用于setup.py进程, 这里讨论的相同问题 ,希望它有所帮助!

6
jacoolee

做相对导入是绝对可以的!这就是我的小事:

#first change the cwd to the script path
scriptPath = os.path.realpath(os.path.dirname(sys.argv[0]))
os.chdir(scriptPath)

#append the relative location you want to import from
sys.path.append("../common")

#import your module stored in '../common'
import common.py
6
Gary Beardsley

PYTHONPATH中的默认导入方法已经是“相对”。 PYTHONPATH默认情况下是一些系统库以及原始源文件的文件夹。如果使用-m运行以运行模块,则当前目录将添加到PYTHONPATH。因此,如果程序的入口点在Proj中,那么使用import Common.Common应该在Server.py和Client.py内部工作。

不做相对导入。它不会按你想要的方式工作。

4
Jonathan Sternberg