TensorFlow模块的多级导入未按预期工作

c3frrgcw  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(78)

考虑下面的四段代码。其中,1、2和3都可以工作。我相信4和2类似,应该可以工作。但是它不可以。我得到了下面的错误:module 'tensorflow._api.v2.lite' has no attribute 'tools'
有什么区别?多级导入的行为与单级导入不同吗?
1.

from numpy import ones
a = ones((2, 2))

字符串

import numpy
a = numpy.ones((2, 2))

from tensorflow.lite.tools.flatbuffer_utils import read_model_with_mutable_tensors
read_model_with_mutable_tensors("model.tflite")

import tensorflow.lite.tools.flatbuffer_utils
tensorflow.lite.tools.flatbuffer_utils.read_model_with_mutable_tensors("model.tflite")

ppcbkaq5

ppcbkaq51#

好吧,所以这更像是一个猜测,但也许有人可以证实或反驳(不确定这是正确的词)我的理论。
首先,包和modules之间的区别很重要。模块是普通的.py文件,在这里你可以找到你的类,函数等。包是一种结构化模块的方式,就像文件夹结构一样。包可以有子包,可以有一个__init__.py文件来标记它们为包,并可以选择导入或声明一些东西。
至于你的例子:
对于1,它非常简单。函数ones位于模块numpy中,可以直接导入。请注意,您只导入了ones,不能使用numpy中的任何其他函数。
在源代码中,ones实际上在numpy/core/numeric.py中,但它有装饰器@set_module('numpy'),这似乎将其移动到numpy.导入中。
在2中,您导入了整个numpy名称空间,然后可以调用它提供的所有函数,包括ones
在3中,您可以通过包和子包导入。从文档中:
当导入包时,Python会在sys.path上的目录中搜索该包。
如果你检查source code,你可以看到这些导入的结构实际上是存在的,所以python可以用sys.path找到它。
最困难的部分,4。
在这里,我不是100%确定python是如何管理导入的。
import tensorflow.lite.tools.flatbuffer_utils
它导入模块tensorflow(至少对我来说,当我在IDE中检查变量时),我可以调用tensorflow.__version__而不会出错。
当我试图
import tensorflow.lite.tools.flatbuffer_utils as x

tensorflow.lite.tools.flatbuffer_utils.read_model_with_mutable_tensors("model.tflite")
它抛出了你提到的ImportError。似乎在这种情况下,python逐一检查了这些包的__init__.py,并试图找到所有内容。
在虚拟环境的site-packages文件夹中的tensorflow s __init__.py中,行from ._api.v2 import lite。(对我来说是在venv/Lib/site-packages/tensorflow/_api/v2/lite/__init__.py中)。在这个__init__.py中,没有tools的导入,也没有tools的子包(文件夹),这是ImportError发生的部分。所以看起来对于一些导入,python使用sys.path来查找函数的路径,有时它使用__init__.py
我希望有一个更连贯和令人满意的答案,也许有更多知识的人可以扩展这个答案。

相关问题