根据这个答案,您可以importlib使用import_module相对导入,如下所示:
importlib.import_module('.c', 'a.b')
Run Code Online (Sandbox Code Playgroud)
为什么相对导入对 sklearn.feature_extraction.text 不起作用?
importlib.import_module('.text', 'sklearn.feature_extraction')
Run Code Online (Sandbox Code Playgroud)
我验证了这text是一个模块:
from types import ModuleType
import sklearn.feature_extraction.text
isinstance(sklearn.feature_extraction.text, ModuleType)
Run Code Online (Sandbox Code Playgroud)
退货
True
Run Code Online (Sandbox Code Playgroud)
编辑
我所说的“不起作用”是指它不导入模块。
我正在使用Python 3.4
绝对方式有效:
import importlib
text = importlib.import_module('sklearn.feature_extraction.text')
tfidf = text.TfidfVectorizer()
Run Code Online (Sandbox Code Playgroud)
相对方式不会:
import importlib
text = importlib.import_module('.text', 'sklearn.feature_extraction')
Traceback (most recent call last):
File "<pyshell#28>", line 1, in <module>
text = importlib.import_module('.text', 'sklearn.feature_extraction')
File "C:\Python34\lib\importlib\__init__.py", line 109, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 2249, in _gcd_import
File …Run Code Online (Sandbox Code Playgroud) 我在我的代码和熊猫中使用pandas它们使用了imp结节.现在我收到以下错误/警告
C:\Users\refaelc\AppData\Local\Temp\collection_id-96deaf03-9b39-46c0-a843-63f6101481c1-5289121858290797008.csv
Step07: Compare the downloaded and the template files
C:\Users\refaelc\AppData\Local\Continuum\Anaconda3\lib\importlib\_bootstrap.py:205: ImportWarning: can't resolve package from __spec__ or __package__, falling back on __name__ and __path__
return f(*args, **kwds)
C:\Users\refaelc\AppData\Local\Continuum\Anaconda3\lib\site-packages\_pytest\assertion\rewrite.py:7: DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses
import imp
Item is missing from collections - int
Run Code Online (Sandbox Code Playgroud)
现在我做了一些搜索并意识到imp模块正在被importlib模块取代.我更新了Panda,但没有用.我似乎不太可能需要改变Panda的包裹代码.
有什么想法/修复?
我正在使用烧瓶,并且具有以下结构
<root>
manage_server.py
cas <directory>
--- __init__.py
--- routes.py
--- models.py
--- templates <directory>
--- static <directory>
--- formmodules <directory>
------ __init__.py
------ BaseFormModule.py
------ Interview.py
Run Code Online (Sandbox Code Playgroud)
在routes.py中,我试图在Interview模块中创建Interview类的实例,如下所示
my_module = "Interview"
module = importlib.import_module('formmodules."+my_module)
Run Code Online (Sandbox Code Playgroud)
我在这里看到一个错误
ImportError: No module named formmodules.Interview
Run Code Online (Sandbox Code Playgroud)
有关初始化文件的一些信息:
/cas/formmodules/__init__.py is empty
/cas/__init__.py is where I initialize my flask app.
Run Code Online (Sandbox Code Playgroud)
让我知道了解这些文件中的任何内容是否有帮助。
我有一个已安装的软件包(通常位于 内部\xe2\x80\xa6/lib/pythonX.Y/site-packages/my-package),其中包含(除其他外)资源\xe2\x80\xa6/my-package/a.txt和\xe2\x80\xa6/my-package/b.png. 我想\xe2\x80\xa6/my-package/get_my_resources.py使用以下代码访问这些资源:
txt = importlib.resources.read_text(this_package, 'a.txt')\nimg = importlib.resources.read_binary(this_package, 'b.png')\nRun Code Online (Sandbox Code Playgroud)\n\n我应该用来做什么this_package?当我尝试相对自引用时this_package = '.',出现错误
TypeError: the 'package' argument is required to perform a relative import for '.'\nRun Code Online (Sandbox Code Playgroud)\n 该imp模块已被弃用(自版本 3.4 起),但是基础设施的某些部分(例如pyximport)仍然使用imp.load_dynamic,这会导致较新的 Python 版本出现弃用警告。
在内部,imp.load_dynamic使用importlib-machinery:
from importlib._bootstrap import _load
def load_dynamic(name, path, file=None):
"""**DEPRECATED**
Load an extension module.
"""
import importlib.machinery
loader = importlib.machinery.ExtensionFileLoader(name, path)
# Issue #24748: Skip the sys.modules check in _load_module_shim;
# always load new extension
spec = importlib.machinery.ModuleSpec(
name=name, loader=loader, origin=path)
return _load(spec)
Run Code Online (Sandbox Code Playgroud)
但为所有类型的项目重复此代码(至少需要改进一次)感觉很愚蠢。
importlib的文档提出以下建议:
import importlib.util
import sys
def alternative_load_dynamic(name, path, file=None):
spec = importlib.util.spec_from_file_location(name, path)
module = importlib.util.module_from_spec(spec) …Run Code Online (Sandbox Code Playgroud) 我有一个模块和一个模块加载器。该模块使用 numba。
当我使用 动态加载模块后调用模块的函数时importlib,我遇到了几个错误。当我执行static导入并调用该函数时,一切正常。
当我不使用 numba 时,静态和动态导入都可以正常工作。
这是一个重现问题的简单示例:
模块mymod.py:
from numba import jit
@jit(nopython=True)
def process():
a = 5
res = a + 5
return res
Run Code Online (Sandbox Code Playgroud)
有效的模块加载器:(runb.py静态导入)
import mymod
def main():
res = mymod.process()
print(res)
if __name__=="__main__":
main()
Run Code Online (Sandbox Code Playgroud)
不工作的模块加载器:(run.py动态导入)
from pathlib import Path
import importlib.util
def main():
module_path = "./mymod.py"
spec = importlib.util.spec_from_file_location(Path(module_path).name, module_path)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
res = module.process()
print(res)
if __name__=="__main__":
main()
Run Code Online (Sandbox Code Playgroud)
软件上下文:
这更多是为了理解 Python(在本例中为 3.9)的工作原理,而不是解决实际问题的努力,所以请耐心等待并忽略 m3 的荒谬方式。我只是想复制我正在处理的东西。
我有以下结构:
??? m1.py
??? m2
??? m3
??? __init__.py
??? m3.py
Run Code Online (Sandbox Code Playgroud)
m2/m3/初始化.py:
??? m1.py
??? m2
??? m3
??? __init__.py
??? m3.py
Run Code Online (Sandbox Code Playgroud)
m2/m3/m3.py:
from .m3 import *
Run Code Online (Sandbox Code Playgroud)
从现在开始,我将对 m1.py 进行更改
这是有效的,我期待它的工作:
def m3func():
print('m3 func is here')
Run Code Online (Sandbox Code Playgroud)
这并没有失败,所以它替换了 Mock 的模块。我也期待它的工作方式。
import m2.m3
m2.m3.m3func()
Run Code Online (Sandbox Code Playgroud)
同样的
import sys
from unittest.mock import Mock
sys.modules['m2.m3'] = Mock()
import m2.m3 as alias
alias.m3func()
Run Code Online (Sandbox Code Playgroud)
我不明白这里发生了什么:
import sys
from unittest.mock import Mock
sys.modules['m2.m3'] = Mock()
from m2 import m3
m3.m3func() …Run Code Online (Sandbox Code Playgroud) 给出如下内容:
import importlib
module_path = "mod"
mod = importlib.import_module(module_path, package=None)
print(mod.Foo.Bar.x)
Run Code Online (Sandbox Code Playgroud)
哪里mod.py:
class Foo:
class Bar:
x = 1
Run Code Online (Sandbox Code Playgroud)
mypy file.py --strict 引发以下错误:
file.py:7: error: Module has no attribute "Foo" [attr-defined]
Run Code Online (Sandbox Code Playgroud)
我想知道应该如何进行类型提示,或者这是否是通常会被忽略的东西# type: ignore[attr-defined] (假设代码是必要的,并且唯一的选项是类型提示或忽略类型提示)?
importlib在这种情况下使用使用的方式importlib是有一些路径:
x.y.<changes>.z
Run Code Online (Sandbox Code Playgroud)
哪里<changes>是动态的,其他的都是固定的。我确信该模块将包含正在调用的属性,但由于<changes>,importlib用于导入。
可以概括为:
我不确切地知道我将导入哪个模块,但我知道它将有一个
Foo类。
如果我import A在包含A.py和的目录中执行A.so此.so操作,则将导入该文件。我有兴趣更改导入文件类型的顺序,因此它.py优先于.so,尽管只是暂时的,即在代码行i和j. 这当然可以通过一些 importlib魔法来实现吗?
目前,我通过将 复制.py到一个单独的目录中来解决这个问题,将这个目录放在前面sys.path,然后进行导入,这太糟糕了。
这些.so文件是文件的 cython 编译版本.py。我正在 cython 之上进行一些自定义代码转换,.py即使.so存在“等效项” ,我也需要导入源代码。
下面是一个简单的测试设置。
# A.py
import B
Run Code Online (Sandbox Code Playgroud)
# B.py
import C
print('hello from B')
Run Code Online (Sandbox Code Playgroud)
# C.py
pass
Run Code Online (Sandbox Code Playgroud)
运行python A.py成功会打印出来自 的消息B.py。现在添加B.so(因为.so文件的内容无关紧要,B.so真正成为文本文件就可以了):
# B.so
this is a fake …Run Code Online (Sandbox Code Playgroud) 我正在继续 Ned Batchelder 的 byterun 代码,这是一个用 Python 编写的 Python 解释器,适用于 Python 3.4 以外的 Python 版本。请参阅x-python。
这种方法的长期关注点之一是将导入中的解释器命名空间与解释的程序命名空间分开。
旁白:如果您想要不解释为导入模块的快速解释器,那么不分离命名空间可能是有利的,但是分离模块更正确,尽管速度较慢,并且在解释来自不同 Python 版本的字节码时是必要的。
因此,当解释器遇到IMPORT_NAME操作码时,我想importlib.util基本上拥有一个与解释器遇到的任何导入不同的模块副本。
我现在遇到的问题是这些导入方式不同,这可以使用hasattr().
这是一个例子:
import importlib
module_spec = importlib.util.find_spec("textwrap")
textwrap_module = importlib.util.module_from_spec(module_spec)
submodule = "fill"
print(hasattr(textwrap_module, submodule)) # False
import textwrap
print(hasattr(textwrap, submodule)) # True
Run Code Online (Sandbox Code Playgroud)
我如何使用 获得相同的行为importlib.util?
(但是我应该注意,对于sys,两者都可以找到“path”子模块作为 的属性sys。)
python-importlib ×10
python ×9
python-3.x ×5
import ×2
flask ×1
imp ×1
mypy ×1
numba ×1
pandas ×1
type-hinting ×1
unit-testing ×1