我在Python代码库中看到了some commits,删除了"沙漏导入。"我之前从未见过这个词,我无法通过Python文档或网络搜索找到任何相关内容。
什么是沙漏导入以及何时使用或不使用它们?我最好的猜测是删除它们会生成子模块easier to find,但还有其他原因吗?
从一个链接提交中删除沙漏导入的示例更改:
diff --git a/tensorflow/contrib/slim/python/slim/nets/vgg.py b/tensorflow/contrib/slim/python/slim/nets/vgg.py
index 3c29767f2..d4eb43cbb 100644
--- a/tensorflow/contrib/slim/python/slim/nets/vgg.py
+++ b/tensorflow/contrib/slim/python/slim/nets/vgg.py
@@ -37,13 +37,20 @@ Usage:
@@vgg_16
@@vgg_19
"""
+
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
-import tensorflow as tf
-
-slim = tf.contrib.slim
+from tensorflow.contrib import layers
+from tensorflow.contrib.framework.python.ops import arg_scope
+from tensorflow.contrib.layers.python.layers import layers as layers_lib
+from tensorflow.contrib.layers.python.layers import regularizers
+from tensorflow.contrib.layers.python.layers import utils
+from tensorflow.python.ops import array_ops
+from tensorflow.python.ops import init_ops
+from tensorflow.python.ops import nn_ops
+from tensorflow.python.ops import variable_scope
def vgg_arg_scope(weight_decay=0.0005):
顶级张量流__init__.py
从子模块中导出符号。
# tensorflow/python/__init__.py
...
from tensorflow.python.ops.standard_ops import *
...
# tensorflow/python/ops/standard_ops.py
...
from tensorflow.python.ops.array_ops import *
from tensorflow.python.ops.check_ops import *
from tensorflow.python.ops.clip_ops import *
...
答案 0 :(得分:4)
这里的TensorFlow贡献者:wave :.我们使用术语沙漏 import 指的是从其他模块导入一堆东西的模块 模块并重新导出。您提供了一个很好的例子 问题。
我们关心这一点的原因以及我们称其为 沙漏都与构建图形的形状有关。整体 沙漏模块的重点是,很多用户将依赖它 一个方便的入口点。它本身取决于很多内部 符号。因此,您的依赖图在此过程中有很多优势 一个节点,通过hourglass的中心进行漏斗:
在现实世界中,沙漏会更宽更深
双方。最终用户可以定义依赖于
:standard_ops
和依赖于这些库的二进制文件,以及
内部操作本身可能具有依赖关系。
这个问题是,它使得难以便宜且正确地进行
根据变化进行重建。如果我们更改:check_ops
的一部分,则
:standard_ops
似乎需要重新构建,因为其中之一
依赖关系已更改。并且由于:standard_ops
已被重建,
因此,它的依赖性也必须如此。但是现在我们重新构建了所有最终用户
程序,即使它们实际上并未使用该功能
由:check_ops
提供。我们说构建图
过度逼近实际依赖图。过度近似为
声音-构造仍然是正确的-但可能很浪费。
这在TensorFlow之类的大型代码库上是一个问题,在那里我们有很多 成千上万的测试,当您更改任何代码时,我们都会运行所有受影响的测试, 而且测试可能很昂贵。如果您对“哪些测试是 受此更改影响了吗?”是由于 沙漏依赖性,您在测试上浪费了大量计算能力, 而且您的开发人员还必须等待更长的时间才能合并他们的更改。
您原始问题中的补丁显示了我们如何删除 沙漏依赖性并重写客户端以直接指向那些 实际使用的构建图部分:
这样,如果更改了:check_ops
,我们可以看到我们只需要
重新构建并重新测试一位客户。
这有优点也有缺点。对于真正的最终用户,必须
直接导入很多内部元素很烦人。那不是一个很好的API,
不及import numpy as np
或import tensorflow as tf
好。
此外,它公开了实现细节,这使我们更难
在这些模块周围移动。因此,由于这些原因,我们 do
向用户公开和在Google内部提供沙漏导入。
但是,我们尝试不在我们自己的 中使用沙漏进口
代码库。在我们自己的存储库中,重大更改不是问题,
因为如果我们想重命名,我们可以重命名所有客户
与此同时。我们有tools for working with our build
graphs,并且很乐意这样做,这是
大多数Python程序员都不需要担心。这些工具是
不过非常不错-除了生成美观的视觉图形(如
以上)作为您真正的代码库,它们是强大的查询引擎的基础,
您可以在其中询问系统问题,例如“
暂时依赖:foo
仍在Python 2上运行并属于
给我的团队?”。当您的构建图更多时,此功能将更强大
精确。
TL; DR:沙漏模块是将许多商品的进口捆绑在一起的模块 子模块,并将它们公开给许多客户端模块。我们避免他们 因为它过分逼近了构建图,这使它更加 运行测试成本高昂,而分析代码更困难。