从Python中的相对路径导入

问题:从Python中的相对路径导入

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

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

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

I have a folder for my client code, a folder for my server code, and a folder for code that is shared between them

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

How do I import Common.py from Server.py and Client.py?


回答 0

编辑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”模块。

EDIT Nov 2014 (3 years later):

Python 2.6 and 3.x supports proper relative imports, where you can avoid doing anything hacky. With this method, you know you are getting a relative import rather than an absolute import. The ‘..’ means, go to the directory above me:

from ..Common import Common

As a caveat, this will only work if you run your python as a module, from outside of the package. For example:

python -m Proj

Original hacky way

This method is still commonly used in some situations, where you aren’t actually ever ‘installing’ your package. For example, it’s popular with Django users.

You can add Common/ to your sys.path (the list of paths python looks at to import things):

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

os.path.dirname(__file__) just gives you the directory that your current python file is in, and then we navigate to ‘Common/’ the directory and import ‘Common’ the module.


回答 1

有趣的是,我刚刚遇到了一个相同的问题,我可以通过以下方式获得这项工作:

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

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

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

而且,现在,如果some_stuff要从file:Proj/Common/Common.py导入到file:中Proj/Client/Client.py,就像这样:

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

并且,同样适用于Proj/Server,也适用于setup.py过程, 此处讨论的相同问题,希望对您有所帮助!

Funny enough, a same problem I just met, and I get this work in following way:

combining with linux command ln , we can make thing a lot simper:

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

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

And, now if you want to import some_stuff from file: Proj/Common/Common.py into your file: Proj/Client/Client.py, just like this:

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

And, the same applies to Proj/Server, Also works for setup.py process, a same question discussed here, hope it helps !


回答 2

不要做相对导入。

PEP8

强烈建议不要将相对进口用于包装内进口。

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

更新:Python 2.6和3.x支持正确的相对导入(…) ”。有关更多详细信息,请参见Dave的答案

Don’t do relative import.

From PEP8:

Relative imports for intra-package imports are highly discouraged.

Put all your code into one super package (i.e. “myapp”) and use subpackages for client, server and common code.

Update:Python 2.6 and 3.x supports proper relative imports (…)“. See Dave’s answers for more details.


回答 3

进行相对导入绝对可以!这是我的小事:

#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

Doing a relative import is absolulutely OK! Here’s what little ‘ol me does:

#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

回答 4

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

不要做相对导入。它不会按您希望的那样工作。

The default import method is already “relative”, from the PYTHONPATH. The PYTHONPATH is by default, to some system libraries along with the folder of the original source file. If you run with -m to run a module, the current directory gets added to the PYTHONPATH. So if the entry point of your program is inside of Proj, then using import Common.Common should work inside both Server.py and Client.py.

Don’t do a relative import. It won’t work how you want it to.