如何将python模块添加到syspath?


68

我有一个像这样的文件结构:

Folder
   Common
      foo1.py
   TestFolder
      foo2.py

我想输入foo2.pyfoo1.py。我试过了,但是在Ubuntu上不起作用:

sys.path.append(os.path.abspath('../../'))
from Common import foo1.py

__init__.py文件夹中是否有文件?这就是python创建包的方式,并允许您从该包中导入模块。guide.python-distribute.org/creation.html
布莱恩

我在Common和TestFolder中都具有init.py文件
user284474 2014年

如果要导入,则需要在Folder目录以及子文件夹中使用
Bryan

这个init .py是空的吗?
user284474 2014年

1
是的,它可以是空的。除非您的软件包需要某种配置,但您可以将其保留为空
Bryan

Answers:


114

python如何找到其模块

严格来说,模块是单个python文件,而程序包是包含python文件的文件夹,并带有一个名为的文件(可以为空)__init__.py,以告诉python它是从中导入模块的程序包。在这两种情况下,模块都需要.py扩展,但是导入模块却不需要这样做(请参见下文)。

默认情况下,Python在中查找其模块和软件包$PYTHONPATH

要找出$ PYTHONPATH中包含的内容,请在python(3)中运行以下代码:

import sys
print(sys.path)

如何添加目录

偶尔

在python文件中,您可以通过在python应用程序或脚本的头部添加以下几行,偶尔将路径添加到默认路径:

import sys
sys.path.insert(0, "/path/to/your/package_or_module")

例如:

如果我有一个文件夹:/home/myname/pythonfiles,并且我想导入该module_1.py目录中的file ,则将其添加到代码的开头部分:

import sys
sys.path.insert(0, "/home/myname/pythonfiles")

我可以module_1.py通过以下方式简单地导入文件:

import module_1

当我创建一个并想要从包中导入模块时,我需要在中创建一个文件夹$PYTHONPATH,其中包含这些模块,以及一个名为(可以为空)的文件__init__.py

例如:

要从名为my_packagein 的包(文件夹)中导入,请像示例1中一样/home/myname/pythonfiles,将/home/myname/pythonfiles路径添加到your $PYTHONPATH,然后module_2.py只需使用以下命令导入名为(在package文件夹内)的模块:

from <packagename> import module_2

将目录$PYTHONPATH永久添加:

将以下行添加到您的~/.profile文件。

export PYTHONPATH=$PYTHONPATH:/path/you/want/to/add

子目录

在一个包中,子目录并不像这样包含。您需要“链接”目录。要导入模块module_3.py,请在文件夹subfolder内的文件夹中packagename

import packagename.subfolder.module_3

考虑到包中的所有子文件夹都包含自己的__init__.py文件。

当模块与脚本或应用程序位于同一目录中时

当模块与脚本或应用程序位于同一目录中时,无需插入模块的路径,它会自动添加。

例:

如果我有一个包含script.py和的文件夹,则module.py可以通过以下方式简单地导入该模块:

import module

我也想建议阅读python.org/dev/peps/pep-0328,特别是如果您要定位Python 3(或计划将来定位)
zaadeh

为什么printenv PYTHONPATH什么都不是?
Stevie G

1
sys.path.append("/path/to/your/package_or_module")还为默认值添加了一条路径,因此不易混淆。相比sys.path.insert(0,...)其具有0作为第一个参数。
Paul Rougieux

1
@PaulRougieux:追加到路径的问题是您的模块可能已经存在于路径的其他位置(例如,在一个.egg文件中),您将选择模块的版本,而不是文件中的那个版本。
snark

6

使用相对导入的正确方法是:

from ..Common import foo1

而且您还需要__init__.py在所有文件夹中添加一个。


1
谢谢。但是,如果我有一个包含两个文件夹的模块,该如何导入?从...文件夹不工作
user284474 2014年

它可以在单个级别上使用吗?
西尔文·皮诺

只需一个级别,它就可以工作。
user284474

好的,您能接受这个答案吗?对于多层而言,虽然您可以提出不同的问题,但首先请看一下这个问题和此答案,以获取在包装内调用模块的最佳方法
Sylvain Pineau 2014年

这对于Python 2或Python 3是正确的吗?或两者?
Alex

2

注意:对于最新版本的python 3,此答案已过时,但对于较早的版本,此答案在此处。有关更多信息,请阅读注释和https://www.python.org/dev/peps/pep-0420/


基本上,每个要添加到syspath的带有python代码的文件夹都需要一个__init__.py文件。这些__init__.py文件可以为空。


据我了解,情况已不再如此,该目录现在成为“命名空间”。
亚伦·霍尔

@AaronHall有趣,来源?
don.joey

1
试试看,以获取证据:这python -c "from pathlib import Path; Path('ns').mkdir(); Path('ns/mod.py').write_text('''print('mod.py')'''); import ns.mod; from shutil import rmtree; rmtree('ns')"也是一些相关的文档PEP 420,它描述了名称空间包语义的添加
Aaron Hall
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.