将Pythonsearchpath展开到其他源

我刚刚join了一个具有相当大的现有代码库的项目。 我们在linux中开发,不要使用IDE。 我们通过命令行运行。 我想弄清楚如何让Python来search正确的path,当我运行项目模块。 例如,当我运行如下的东西:

python someprojectfile.py 

我明白了

 ImportError: no module named core.'somemodule' 

我得到这个import的所有我认为这是一个问题的道路。

TLDR:

如何在导入语句中search~/codez/project/以及* .py文件的所有文件和文件夹。

有几个可能的方法来做到这一点:

  • 将环境variablesPYTHONPATH设置为冒号分隔的目录列表以search导入的模块。
  • 在你的程序中,使用sys.path.append('/path/to/search')来添加Python想要search导入模块的目录名称。 sys.path就是Python每次被要求导入模块时search的目录列表,你可以根据需要修改它(尽pipe我不build议删除任何标准目录!)。 当Python启动时,任何放在环境variablesPYTHONPATH中的目录都将被插入到sys.path
  • 使用site.addsitedir将一个目录添加到sys.path 。 这与简单附加的区别在于,当您使用addsitedir ,它也会在该目录中查找.pth文件,并使用它们根据文件的内容将其他目录添加到sys.path 。 请参阅文档以获取更多细节。

你想使用哪一个取决于你的情况。 请记住,当您将项目分发给其他用户时,他们通常会以Python代码文件将被Python导入程序自动检测到的方式进行安装(即,软件包通常安装在site-packages目录中),所以如果您代码中的sys.path ,这可能是不必要的,甚至可能在另一台计算机上运行该代码时产生不利影响。 对于开发,我会冒险猜测设置PYTHONPATH通常是最好的方法。

然而,当你使用的东西只是运行在你自己的计算机上(或者当你有非标准的设置,例如有时在web应用程序框架中),做这样的事情并不罕见

 from os.path import dirname sys.path.append(dirname(__file__)) 

你还应该阅读关于python软件包, http://docs.python.org/tutorial/modules.html 。 从你的例子中,我猜想你真的有〜/ codez /项目的包。 python目录中的__init__.py文件将一个目录映射到一个名称空间中。 如果你的子目录都有一个__init__.py文件,那么你只需要添加basedir到你的PYTHONPATH中,例如:

PYTHONPATH = $ PYTHONPATH:$ HOME / adaifotis /项目

除了testing你的PYTHONPATH环境variables,就像David解释的那样,你可以用python来testing它:

 $ python >>> import project # should work if PYTHONPATH set >>> import sys >>> for line in sys.path: print line # print current python path 

我阅读这个问题寻找答案,并不喜欢其中任何一个。

所以我写了一个快速而肮脏的解决scheme 只要把它放在你的sys.path的某个地方,它就会在folder (来自当前的工作目录)或abspath下添加任何目录:

 #using.py import sys, os.path def all_from(folder='', abspath=None): """add all dirs under `folder` to sys.path if any .py files are found. Use an abspath if you'd rather do it that way. Uses the current working directory as the location of using.py. Keep in mind that os.walk goes *all the way* down the directory tree. With that, try not to use this on something too close to '/' """ add = set(sys.path) if abspath is None: cwd = os.path.abspath(os.path.curdir) abspath = os.path.join(cwd, folder) for root, dirs, files in os.walk(abspath): for f in files: if f[-3:] in '.py': add.add(root) break for i in add: sys.path.append(i) >>> import using, sys, pprint >>> using.all_from('py') #if in ~, /home/user/py/ >>> pprint.pprint(sys.path) [ #that was easy ] 

我喜欢它,因为我可以为一些随机工具提供一个文件夹,而不是将其作为软件包或任何其他软件的一部分,仍然可以通过几行代码访问其中的一部分(或全部)。

我find的最简单的方法是创build一个文件“any_name.pth”,并将其放在“\ Lib \ site-packages”文件夹中。 你应该在python安装的地方find这个文件夹。

在该文件中,放置一个您想保留模块以供导入的目录列表。 例如,在这个文件中做一个这样的行:

C:\ Users \用户例如… \实例

您将能够通过在python中运行它来告诉它工作:

 import sys for line in sys: print line 

你会看到你的目录打印出来,除其他外,你也可以导入。 现在你可以像导入那样简单地导入位于该目录中的“mymodule.py”文件:

 import mymodule 

这不会导入子文件夹。 为此,您可以想象创build一个python脚本来创build一个.pth文件,其中包含您定义的文件夹的所有子文件夹。 它可能在启动时运行。

我知道这个post有点老了,但是花了我一些时间去了解这个,所以我想分享一下。

在我的项目中,我将主脚本放在父目录中,为了区分这些模块,我将所有的支持模块放在一个名为“modules”的子文件夹中。 在我的主脚本中,我导入这些模块(对于一个名为report.py的模块):

从modules.report导入报告,reportError

如果我打电话给我的主要脚本,这是有效的。 不过,我想通过在每个模块中包含一个main()来testing每个模块,并直接调用它们,如下所示:

python modules \ report.py

现在Python抱怨说找不到“一个叫模块的模块”。 这里的关键是,默认情况下,Python在其searchpath中包含脚本的文件夹,但不包括CWD。 那么这个错误说的是,“我无法find模块子文件夹”。 这是因为report.py模块所在的目录没有“modules”子目录。

我发现最简单的解决scheme是通过在顶部包括这个来追加Pythonsearchpath中的CWD:

导入系统

sys.path.append( “”)

现在PythonsearchCWD(当前目录),find“modules”子文件夹,一切正常。