der*_*red 1022 python configuration python-module python-import
如何在完整路径下加载Python模块?请注意,该文件可以位于文件系统中的任何位置,因为它是一个配置选项.
Seb*_*tau 1166
对于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()
Run Code Online (Sandbox Code Playgroud)
对于Python 3.3和3.4使用:
from importlib.machinery import SourceFileLoader
foo = SourceFileLoader("module.name", "/path/to/file.py").load_module()
foo.MyClass()
Run Code Online (Sandbox Code Playgroud)
(虽然这在Python 3.4中已被弃用.)
Python 2使用:
import imp
foo = imp.load_source('module.name', '/path/to/file.py')
foo.MyClass()
Run Code Online (Sandbox Code Playgroud)
编译的Python文件和DLL有相同的便利功能.
也可以看看.http://bugs.python.org/issue21436.
Dar*_*zer 391
向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
Run Code Online (Sandbox Code Playgroud)
Mil*_*uss 25
要导入模块,您需要临时或永久地将其目录添加到环境变量中.
import sys
sys.path.append("/path/to/my/modules/")
import my_module
Run Code Online (Sandbox Code Playgroud)
.bashrc将以下行添加到您的文件(在Linux中)并source ~/.bashrc在终端中执行:
export PYTHONPATH="${PYTHONPATH}:/path/to/my/modules/"
Run Code Online (Sandbox Code Playgroud)
Credit/Source:saarrrr,另一个stackexchange 问题
Sam*_*ahl 23
如果您的顶级模块不是文件但是打包为__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)
Run Code Online (Sandbox Code Playgroud)
如果没有这一行,当执行exec_module时,它会尝试将顶级__init__.py中的相对导入绑定到顶级模块名称 - 在本例中为"mymodule".但是"mymodule"尚未加载,因此您将收到错误"SystemError:Parent module'mymodule'未加载,无法执行相对导入".因此,您需要在加载名称之前绑定该名称.原因是相对导入系统的基本不变量:"不变量持有是如果你有sys.modules ['spam']和sys.modules ['spam.foo'](正如你在上面的导入之后那样) ),后者必须作为前者的foo属性出现" 如此处所讨论的那样.
nco*_*lan 21
听起来你不想专门导入配置文件(它有很多副作用和涉及的额外复杂性),你只想运行它,并能够访问生成的命名空间.标准库以runpy.run_path的形式专门为其提供API :
from runpy import run_path
settings = run_path("/path/to/file.py")
Run Code Online (Sandbox Code Playgroud)
该接口在Python 2.7和Python 3.2+中可用
ctc*_*rry 19
您也可以执行类似这样的操作,并将配置文件所在的目录添加到Python加载路径中,然后执行常规导入,假设您事先知道文件的名称,在本例中为"config".
凌乱,但它的确有效.
configfile = '~/config.py'
import os
import sys
sys.path.append(os.path.dirname(os.path.expanduser(configfile)))
import config
Run Code Online (Sandbox Code Playgroud)
ジョー*_*ョージ 19
添加到Sebastian Rittau的答案:至少对于CPython来说,有pydoc,虽然没有正式声明,但导入文件就是它的作用:
from pydoc import importfile
module = importfile('/path/to/module.py')
Run Code Online (Sandbox Code Playgroud)
附言。为了完整起见,在撰写本文时引用了当前的实现:pydoc.py,我很高兴地说,按照xkcd 1987的精神,它没有使用问题 21436中提到的任何实现- 在至少,不是逐字逐句。
zub*_*ber 17
你可以使用
load_source(module_name, path_to_file)
Run Code Online (Sandbox Code Playgroud)
来自imp模块的方法.
Mad*_*ist 13
我想出了一个稍微修改过的@ 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)
Run Code Online (Sandbox Code Playgroud)
在显式中编码路径的优点SourceFileLoader是机器不会试图从扩展中找出文件的类型.这意味着您可以.txt使用此方法加载类似文件的内容,但如果spec_from_file_location没有指定加载器.txt则无法执行此操作,因为它不在importlib.machinery.SOURCE_SUFFIXES.
小智 12
你的意思是加载还是导入?
您可以操作sys.path列表指定模块的路径,然后导入模块.例如,给定一个模块:
/foo/bar.py
Run Code Online (Sandbox Code Playgroud)
你可以这样做:
import sys
sys.path[0:0] = ['/foo'] # puts the /foo directory at the start of your path
import bar
Run Code Online (Sandbox Code Playgroud)
sor*_*rin 12
下面是一些适用于所有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())
Run Code Online (Sandbox Code Playgroud)
我测试了它.它可能很难看但到目前为止是唯一一个适用于所有版本的产品.
Kum*_* KS 12
如果我们在同一个项目中有脚本,但在不同的目录中,我们可以通过以下方法解决这个问题。
在这种情况下utils.py是src/main/util/
import sys
sys.path.append('./')
import src.main.util.utils
#or
from src.main.util.utils import json_converter # json_converter is example method
Run Code Online (Sandbox Code Playgroud)
Chr*_*way 11
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')
Run Code Online (Sandbox Code Playgroud)
小智 8
我相信你可以使用imp.find_module()和imp.load_module()加载指定的模块.您需要将模块名称从路径中分离出来,即如果您想加载/home/mypath/mymodule.py,则需要执行以下操作:
imp.find_module('mymodule', '/home/mypath/')
Run Code Online (Sandbox Code Playgroud)
......但那应该完成工作.
小智 8
您可以使用pkgutil模块(特别是walk_packages方法)获取当前目录中的包列表。从那里使用importlib机器导入您想要的模块是微不足道的:
import pkgutil
import importlib
packages = pkgutil.walk_packages(path='.')
for importer, name, is_package in packages:
mod = importlib.import_module(name)
# do whatever you want with module now, it's been imported!
Run Code Online (Sandbox Code Playgroud)
创建 Python 模块test.py:
import sys
sys.path.append("<project-path>/lib/")
from tes1 import Client1
from tes2 import Client2
import tes3
Run Code Online (Sandbox Code Playgroud)
创建 Python 模块test_check.py:
from test import Client1
from test import Client2
from test import test3
Run Code Online (Sandbox Code Playgroud)
我们可以从模块导入导入的模块。
有一个专门用于此的软件包:
from thesmuggler import smuggle
# À la `import weapons`
weapons = smuggle('weapons.py')
# À la `from contraband import drugs, alcohol`
drugs, alcohol = smuggle('drugs', 'alcohol', source='contraband.py')
# À la `from contraband import drugs as dope, alcohol as booze`
dope, booze = smuggle('drugs', 'alcohol', source='contraband.py')
Run Code Online (Sandbox Code Playgroud)
它在 Python 版本(Jython 和 PyPy 也是)中进行了测试,但根据项目的大小,它可能有点过分。
小智 5
Python 3.4 的这块区域似乎非常难懂!然而,通过使用 Chris Calloway 的代码进行一些黑客攻击,我设法使一些工作正常进行。这是基本功能。
def import_module_from_file(full_path_to_module):
"""
Import a module given the full path/filename of the .py file
Python 3.4
"""
module = None
try:
# Get module name and path from full path
module_dir, module_file = os.path.split(full_path_to_module)
module_name, module_ext = os.path.splitext(module_file)
# Get module "spec" from filename
spec = importlib.util.spec_from_file_location(module_name,full_path_to_module)
module = spec.loader.load_module()
except Exception as ec:
# Simple error printing
# Insert "sophisticated" stuff here
print(ec)
finally:
return module
Run Code Online (Sandbox Code Playgroud)
这似乎使用了 Python 3.4 中未弃用的模块。我不假装明白为什么,但它似乎在程序中工作。我发现 Chris 的解决方案在命令行上有效,但在程序内部无效。
| 归档时间: |
|
| 查看次数: |
800556 次 |
| 最近记录: |