2012-04-15 146 views
44

我有一个模块foo,包含util.py和bar.py.导入python模块不在路径上

我想在IDLE或python会话中导入它。我如何去做这件事?

我找不到有关如何导入不在当前目录或默认python PATH中的模块的文档。 试图import "<full path>/foo/util.py", 和from "<full path>" import util

最接近之后,我能得到是

import imp 
imp.load_source('foo.util','C:/.../dir/dir2/foo') 

这给了我许可的Windows 7拒绝

+0

还值得看看这[相关问题](http://stackoverflow.com/questions/15109548/set-pythonpath-before-import-statements)。特别是,我喜欢那里的[最佳答案](http://stackoverflow.com/a/15109660/95852),因为它清楚了sys.path的更改的安全性。 – 2015-03-17 18:49:09

+0

[How to import a module given given the full path?](http://stackoverflow.com/questions/67631/how-to-import-a-module-given-the-full-path) – 2015-11-30 02:03:41

回答

62

一种方法是简单地修改你的path

import sys 
sys.path.append('C:/full/path') 
from foo import util,bar 

注意,这需要FOO是一个Python包,即包含一个__init__.py文件。如果您不想修改sys.path,您可以also modify the PYTHONPATH environment variableinstall the module on your system。请注意,这意味着该目录中的其他目录或.py文件可能会无意中加载。

因此,您可能想使用imp.load_source来代替。它需要的文件名,而不是一个目录(以当前用户被允许读取文件):

import imp 
util = imp.load_source('util', 'C:/full/path/foo/util.py') 
+0

它的工作原理,但现在当试图通过使用方法使用util.method,它说'方法'没有定义。但我可以通过util.method来使用它。为什么? – Vort3x 2012-04-15 11:54:38

+2

由于您尚未定义'方法',因此只有''util''中的'method'。如果需要,你可以定义'method = util.method'。 – katrielalex 2012-04-15 11:57:43

+0

请注意,从foo import *开始的编码是不好的编码,除非你只是在shell中进行黑客入侵。 – katrielalex 2012-04-15 11:58:01

5

你可以使用PYTHONPATH环境变量定义模块,搜索路径,或者手动修改sys.path目录列表。

请参阅Module Search Path关于python.org的文档。

2

试试这个

import sys 
sys.path.append('c:/.../dir/dir2') 
import foo 
+1

-1因为追加到Python路径是一个不好的解决方案。它可以工作,但是它比imp.load_source严格得更糟,因为用户可能不想修改任何系统路径,或者可能正在计算机上工作,因为他或她不能这样做。这实际上是Python中最烦人的“特性”之一,否则就是一种优雅的语言。很愚蠢的是,你不能只给一个字符串命名一个路径到另一个.py文件。考虑到你不能做到这一点,通过使用imp来防止改变系统路径是非常好的。 – ely 2012-04-16 17:51:28

+1

@EMS啊..我明白你的意思了,以前我没有意识到,但现在你明白了。感谢您指出了这一点。 (我现在可能需要修改我自己的一些代码:) – Levon 2012-04-16 17:58:38

+3

别担心。这是'sys.path'(或至少*一个*预期用例)的预期目的。 F先生(显然以前是EMS)是错误的。由于phihag在对他的回答相同的-1评论中的回应中注意到,“sys.path”与整个系统路径不相关。 – 2015-03-17 18:36:01

1

继phihag的提示,我有这样的解决方案。只要将源文件的路径设置为load_src,它就会加载它。您还必须提供一个名称,以便您可以使用该名称导入此模块。我喜欢做这种方式,因为它更明确:

def load_src(name, fpath): 
    import os, imp 
    return imp.load_source(name, os.path.join(os.path.dirname(__file__), fpath)) 

load_src("util", "../util.py") 
import util 

print util.method() 

另一个(不太明显)的方式是这样的:

util = load_src("util", "../util.py") # "import util" is implied here 

print util.method() # works, util was imported by the previous line 

编辑:的方法重写以使其更清晰。