python导入模块不存在路径正确_导入python模块不在路径上

我有一个模块foo,包含util.py和bar.py。

我想在空闲或Python会话中导入它。我该怎么办?

我找不到有关如何导入不在当前目录或默认python路径中的模块的文档。在尝试过import"/foo/util.py"之后,和from"" import util。

我能得到的最接近的是

import imp

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

这给了我在Windows7上被拒绝的许可。

同样值得一看这个相关的问题。特别是,我喜欢上面的答案,因为它清楚地说明了sys.path变更的安全性。

如何导入给定完整路径的模块的可能副本?

一种方法是简单地修改你的路径:

import sys

sys.path.append('C:/full/path')

from foo import util,bar

注意,这要求foo是一个python包,即包含一个__init__.py文件。如果不想修改sys.path,也可以修改PYTHONPATH环境变量或在系统上安装模块。注意,这意味着该目录中的其他目录或.py文件可能会意外加载。

因此,您可能希望使用imp.load_source。它需要文件名,而不是目录(当前用户可以读取的文件):

import imp

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

它可以工作,但现在当尝试通过方法使用util.method时,它说"method"未定义。但我可以通过util.method使用它。为什么?

因为您没有定义method,所以只有"util中的method"。如果需要,可以定义method = util.method。

注意,除非您只是在shell中进行黑客攻击,否则from foo import *是一种糟糕的编码。

@KatrielAlex谢谢。我使用的是来自foo import util,而不是来自foo import*。所以别担心;)

@旋涡3x好,这使得util在您的名称空间中可用。为什么您希望以method的名义提供util.method?这意味着你必须确保在bar中没有另一个method,从而击败模块系统的整个点,即不必担心名称冲突。

@phihag因为我对python不熟悉,所以我知道它现在是如何工作的:)

@Wooble改为套装。需要__init__.py。观察mkdir foo; touch foo/util.py; python -c 'from foo import util'和touch foo/__init__.py; python -c 'from foo import util'。

-1,因为附加到python路径是一个错误的解决方案。它可以工作,但严格来说比imp.load_source更糟,因为用户可能不想修改任何系统路径,或者可能正在无法修改的计算机上工作。这实际上是Python中最令人讨厌的"特性"之一,否则它就是一种优雅的语言。你不能给import一个字符串来命名另一个.py文件的路径,这太愚蠢了。如果您不能,那么使用imp来防止系统路径发生变化就更好了。

@ems python文档明确提到sys.path。如果用户不能修改sys.path,那么很可能imp模块也被阻塞了(注意python的sys.path与系统的PATH无关)。就个人而言,我不认为用名称而不是文件名来加载模块是愚蠢的;它允许在系统范围内安装python包(例如,在2.5版上,您可能希望为您的可选json模块提供服务)。添加了一个警告注释。

好吧,是的,从一个包中导入确实需要__init__.py,尽管如果没有它,/foo被添加到sys.path,那么import util和import bar都可以工作。(投票改为+1)

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

请参见python.org上的模块搜索路径文档。

试一试

import sys

sys.path.append('c:/.../dir/dir2')

import foo

-1,因为附加到python路径是一个错误的解决方案。它可以工作,但是它比imp.load_source更糟糕,因为用户可能不想修改任何系统路径,或者可能在无法修改的计算机上工作。这实际上是Python中最令人讨厌的"特性"之一,否则它就是一种优雅的语言。你不能给import一个字符串来命名另一个.py文件的路径,这很愚蠢。如果您不能,那么使用IMP来防止系统路径发生变化就更好了。

嗯…我知道你在说什么,我以前没有意识到,但现在你说的话已经很清楚了。谢谢你指出这一点。(我现在可能需要修改一些自己的代码:)

别担心。这是sys.path的预期用途(或至少是预期的用例)。F先生(显然以前是EMS)是错的。正如phihag在对他答案的相同-1评论的回复中指出的,sys.path与整个系统路径无关。

@伊利看来,在python3.3之后,imp.load_source(load_module)已经被弃用了。还有什么可以替代的呢?

根据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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值