当前位置:  开发笔记 > 编程语言 > 正文

给定完整路径如何导入模块?

如何解决《给定完整路径如何导入模块?》经验,为你挑选了12个好方法。

如何在完整路径下加载Python模块?请注意,该文件可以位于文件系统中的任何位置,因为它是一个配置选项.



1> Sebastian Ri..:

对于Python 3.5+使用:

import importlib.util
spec = importlib.util.spec_from_file_location("module.name", "/path/to/file.py")
foo = importlib.util.module_from_spec(spec)
spec.loader.exec_module(foo)
foo.MyClass()

对于Python 3.3和3.4使用:

from importlib.machinery import SourceFileLoader

foo = SourceFileLoader("module.name", "/path/to/file.py").load_module()
foo.MyClass()

(虽然这在Python 3.4中已被弃用.)

Python 2使用:

import imp

foo = imp.load_source('module.name', '/path/to/file.py')
foo.MyClass()

编译的Python文件和DLL有相同的便利功能.

也可以看看.http://bugs.python.org/issue21436.


@SridharRatnakumar"imp.load_source"的第一个参数的值只设置返回模块的`.__ name__`.它不会影响加载.
如果我知道名称空间 - 'module.name' - 我已经使用了`__import__`.
@DanD. - `imp.load_source()`的第一个参数确定在`sys.modules`字典中创建的新条目的键,因此第一个参数确实影响加载.
从版本3.4开始,不推荐使用`imp`模块:`imp`包正在等待弃用,转而使用`importlib`.
@AXO以及更多关于人们想知道为什么像这个简单和基本的东西*变得如此复杂.它不是很多其他语言.
@ Mahesha999因为importlib.import_module()不允许你按文件名导入模块,这就是最初的问题.
对于Python 3.5+,如果`/ path/to/file.py`隐式导入兄弟(例如`import bar`导入`/ path/to/bar.py`),解决方案会产生`ModuleNotFoundError:No module named' bar'`.有任何解决这个问题的方法吗?
是的,我修改了我的答案以反映Python 3.4+.
这是复制的想法:""import module.name as foo"",如果你的工作目录是/ path/to ?? 另外,这里的foo是什么?
我在Python 3.5.2并且我发现它****只有在文件的扩展名为.py时才有效
@Paolo Celati在Python 3.5+中你应该使用importlib.import_module(module_name).有些像这样.sys,path.append(path_to_file)module = importlib.import_module(module_name)
`importlib.util.spec_from_file_location`不会导入不以..py` =结尾的文件(

2> Daryl Spitze..:

向sys.path添加路径(使用imp)的优点是,当从单个包导入多个模块时,它简化了操作.例如:

import sys
# the mock-0.3.1 dir contains testcase.py, testutils.py & mock.py
sys.path.append('/foo/bar/mock-0.3.1')

from testcase import TestCase
from testutils import RunTests
from mock import Mock, sentinel, patch


:-)也许你的问题更适合作为StackOverflow问题,而不是对答案的评论.
我们如何使用`sys.path.append`指向单个python文件而不是目录?
请注意Python缓存import语句的事实.在极少数情况下,您有两个不同的文件夹共享一个类名(classX),添加路径到sys.path,导入classX,删除路径和重复reamaining路径的方法将不起作用.Python将始终从其缓存的第一个路径加载该类.就我而言,我的目标是创建一个插件系统,其中所有插件都实现了特定的classX.我最终使用[SourceFileLoader](http://stackoverflow.com/a/67692),请注意其[弃用是有争议的](http://bugs.python.org/issue21436).
对于所有试图将文件包含在其路径中的人......根据定义"shell路径是以冒号分隔的目录列表".我对python比较陌生,但是python路径也遵循我所看到的unix设计原则.如果我错了,请纠正我.
python路径可以包含zip存档,"egg"(一种复杂的zip存档)等.模块可以从中导入.所以路径元素确实是_containers_文件,但它们不一定是目录.

3> Miladiouss..:

要导入模块,您需要临时或永久地将其目录添加到环境变量中.

暂时
import sys
sys.path.append("/path/to/my/modules/")
import my_module
永久性

.bashrc将以下行添加到您的文件(在Linux中)并source ~/.bashrc在终端中执行:

export PYTHONPATH="${PYTHONPATH}:/path/to/my/modules/"

Credit/Source:saarrrr,另一个stackexchange 问题


如果要在其他地方的Jupyter笔记本中进行项目生产,则此“临时”解决方案是一个很好的答案。

4> Sam Grondahl..:

如果您的顶级模块不是文件但是打包为__init__.py的目录,那么接受的解决方案几乎可以正常工作,但并不完全.在Python 3.5+中需要以下代码(请注意以'sys.modules'开头的添加行):

MODULE_PATH = "/path/to/your/module/__init__.py"
MODULE_NAME = "mymodule"
import importlib
import sys
spec = importlib.util.spec_from_file_location(MODULE_NAME, MODULE_PATH)
module = importlib.util.module_from_spec(spec)
sys.modules[spec.name] = module 
spec.loader.exec_module(module)

如果没有这一行,当执行exec_module时,它会尝试将顶级__init__.py中的相对导入绑定到顶级模块名称 - 在本例中为"mymodule".但是"mymodule"尚未加载,因此您将收到错误"SystemError:Parent module'mymodule'未加载,无法执行相对导入".因此,您需要在加载名称之前绑定该名称.原因是相对导入系统的基本不变量:"不变量持有是如果你有sys.modules ['spam']和sys.modules ['spam.foo'](正如你在上面的导入之后那样) ),后者必须作为前者的foo属性出现" 如此处所讨论的那样.



5> ncoghlan..:

听起来你不想专门导入配置文件(它有很多副作用和涉及的额外复杂性),你只想运行它,并能够访问生成的命名空间.标准库以runpy.run_path的形式专门为其提供API :

from runpy import run_path
settings = run_path("/path/to/file.py")

该接口在Python 2.7和Python 3.2+中可用



6> ctcherry..:

您也可以执行类似这样的操作,并将配置文件所在的目录添加到Python加载路径中,然后执行常规导入,假设您事先知道文件的名称,在本例中为"config".

凌乱,但它的确有效.

configfile = '~/config.py'

import os
import sys

sys.path.append(os.path.dirname(os.path.expanduser(configfile)))

import config



7> zuber..:

你可以使用

load_source(module_name, path_to_file) 

来自imp模块的方法.


抬头说imp现在已被弃用了.

8> Mad Physicis..:

我想出了一个稍微修改过的@ SebastianRittau的精彩答案(对于我认为的Python> 3.4),这将允许您使用任何扩展名作为模块加载文件spec_from_loader而不是spec_from_file_location:

from importlib.util import spec_from_loader, module_from_spec
from importlib.machinery import SourceFileLoader 

spec = spec_from_loader("module.name", SourceFileLoader("module.name", "/path/to/file.py"))
mod = module_from_spec(spec)
spec.loader.exec_module(mod)

在显式中编码路径的优点SourceFileLoader是机器不会试图从扩展中找出文件的类型.这意味着您可以.txt使用此方法加载类似文件的内容,但如果spec_from_file_location没有指定加载器.txt则无法执行此操作,因为它不在importlib.machinery.SOURCE_SUFFIXES.



9> 小智..:

你的意思是加载还是导入?

您可以操作sys.path列表指定模块的路径,然后导入模块.例如,给定一个模块:

/foo/bar.py

你可以这样做:

import sys
sys.path[0:0] = ['/foo'] # puts the /foo directory at the start of your path
import bar


`sys.path [0:0] = ['/ foo']`
B/c sys.path [0] = xy覆盖第一个路径项,而path [0:0] = xy等同于path.insert(0,xy)
hm path.insert为我工作,但[0:0]技巧没有.
“显式优于隐式。”那么为什么不使用“ sys.path.insert(0,...)”而不是“ sys.path [0:0]”呢?

10> sorin..:

下面是一些适用于所有Python版本的代码,从2.7-3.5甚至其他版本.

config_file = "/tmp/config.py"
with open(config_file) as f:
    code = compile(f.read(), config_file, 'exec')
    exec(code, globals(), locals())

我测试了它.它可能很难看但到目前为止是唯一一个适用于所有版本的产品.



11> Chris Callow..:
def import_file(full_path_to_module):
    try:
        import os
        module_dir, module_file = os.path.split(full_path_to_module)
        module_name, module_ext = os.path.splitext(module_file)
        save_cwd = os.getcwd()
        os.chdir(module_dir)
        module_obj = __import__(module_name)
        module_obj.__file__ = full_path_to_module
        globals()[module_name] = module_obj
        os.chdir(save_cwd)
    except:
        raise ImportError

import_file('/home/somebody/somemodule.py')


为什么在标准库已经解决这个问题时会编写14行错误代码?您尚未对full_path_to_module的格式或内容或os.whatever操作进行错误检查; 并使用catch-all`exce:`子句很少是一个好主意.
@ChrisJohnson`标准库已经解决了这个问题,但是python有一种讨厌的习惯,就是不能向后兼容......因为经过检查的答案说3.3之前和之后有两种不同的方式.在那种情况下,我宁愿编写自己的通用功能而不是动态检查版本.是的,也许这个代码没有太好的错误保护,但它显示了一个想法(这是os.chdir(),我还没有它),基于此我可以编写更好的代码.因此+1.

12> 小智..:

我相信你可以使用imp.find_module()imp.load_module()加载指定的模块.您需要将模块名称从路径中分离出来,即如果您想加载/home/mypath/mymodule.py,则需要执行以下操作:

imp.find_module('mymodule', '/home/mypath/')

......但那应该完成工作.

推荐阅读
周扒pi
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有