科学堆栈存储库中的 Python 相对导入与绝对导入

标签 python numpy import scipy

我正在查看以下软件包(numpy、scipy、scikit-learn、scikit-image)以获取如何构建我自己的软件的灵感。我列出的软件包中似乎有以下约定:

  1. 在所有情况下,导入都会出现在每个文件的顶部
  2. 在“模块代码”中,所有“内部包”导入都是使用相对导入完成的
  3. 在“模块代码”中,所有“外部包”导入都是使用绝对导入完成的
  4. 在“测试代码”中,仅使用绝对导入

有人可以解释一下为什么要使用这些规则,或者给我指出一些引用资料吗?在他们所有的编码约定指南中,他们都声明遵循这个标准,但我没有看到原因的解释。我很想知道,所以非常感谢任何帮助!

这里有一些代码示例来帮助说明...

“模块代码示例” (sklearn/decomposition/pca.py)

from math import log, sqrt
import numbers

import numpy as np
from scipy import linalg
from scipy.special import gammaln
from scipy.sparse import issparse
from scipy.sparse.linalg import svds

from ..externals import six

from .base import _BasePCA
from ..base import BaseEstimator, TransformerMixin
from ..utils import deprecated
from ..utils import check_random_state, as_float_array
from ..utils import check_array
from ..utils.extmath import fast_logdet, randomized_svd, svd_flip
from ..utils.extmath import stable_cumsum
from ..utils.validation import check_is_fitted


def _assess_dimension_(spectrum, rank, n_samples, n_features):
    """Compute the likelihood of a rank ``rank`` dataset

    The dataset is assumed to be embedded in gaussian noise of shape(n,
    dimf) having spectrum ``spectrum``.

    Parameters
    ----------
    spectrum : array of shape (n)
        Data spectrum.

测试代码示例 (sklearn/decomposition/tests/test_pca.py)

import numpy as np
import scipy as sp
from itertools import product

from sklearn.utils.testing import assert_almost_equal
from sklearn.utils.testing import assert_array_almost_equal
from sklearn.utils.testing import assert_true
from sklearn.utils.testing import assert_equal
from sklearn.utils.testing import assert_greater
from sklearn.utils.testing import assert_raise_message
from sklearn.utils.testing import assert_raises
from sklearn.utils.testing import assert_raises_regex
from sklearn.utils.testing import assert_no_warnings
from sklearn.utils.testing import assert_warns_message
from sklearn.utils.testing import ignore_warnings
from sklearn.utils.testing import assert_less

from sklearn import datasets
from sklearn.decomposition import PCA
from sklearn.decomposition import RandomizedPCA
from sklearn.decomposition.pca import _assess_dimension_
from sklearn.decomposition.pca import _infer_dimension_

iris = datasets.load_iris()
solver_list = ['full', 'arpack', 'randomized', 'auto']


def test_pca():
    # PCA on dense arrays
    X = iris.data

    for n_comp in np.arange(X.shape[1]):
        pca = PCA(n_components=n_comp, svd_solver='full')

        X_r = pca.fit(X).transform(X)
        np.testing.assert_equal(X_r.shape[1], n_comp)

最佳答案

我认为您可以通过查看您引用的代码中的导入之一来了解为什么您描述的样式很受欢迎:

from ..externals import six

此导入从 sklearn.internals 包内部获取 six 模块。但six是一个可以单独分发的模块。它已由 sklearn 项目“供应”。供应模块意味着他们将其自己的副本包含在自己的项目中,而不是将其作为外部依赖项。

使您的包裹能够被销售是您可能青睐相对进口的原因之一。如果您的包通常命名为 my_package,但其他一些项目已将其作为 some_other_package.externals.my_package 提供,那么如果您使用相对导入语法,您的内部导入仍然有效。如果您使用绝对导入,它们都会损坏(并且供应商项目需要重写它们中的每一个)。

但它并不完美。如果另一个包也提供一些外部依赖项(您使用绝对导入来访问),则它们将需要编辑您的导入。在修复错误方面,供应商也有一些严重的缺点。如果软件包的供应版本存在安全缺陷,那么包含它的项目也会存在安全缺陷。如果外部包仅访问其依赖项的外部版本,则它可以从外部包的修复中受益,而无需对其本身进行更改。

值得注意的是,一些 Python 开发人员对当前系统的工作方式并不完全满意,因为它可能很难解决一些常见问题。 A recent thread on the Python-dev mailing list讨论了当前支持的不完善之处。

供应可能会很尴尬,而且通常会被下游打包商(例如 Linux 发行版)取消,他们需要能够可靠地修复安全漏洞。但如果没有它,包就很难依赖其依赖项中特定于版本的行为。导入没有版本控制,因此,如果您的代码在 some_package 从版本 1.9 升级到 2.0 时中断,您无能为力(除了也许跳过整个尝试同时支持两个版本的依赖项)。

关于科学堆栈存储库中的 Python 相对导入与绝对导入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49721113/

相关文章:

JAVA,我应该使用 "import"吗?

python - 在 pandas python 中删除 NaN

python - Mypy:帮助装饰者注释多重分派(dispatch)的泛型

PostgreSQL 抛出错误 : "ERROR: permission denied for relation table_name"

python - 在数组数组中查找数组索引的快速方法

python - 对 Python 列表语法感到困惑

使用 genmodel 将 OMG 提供的 XMI 导入到 Ecore-Model?

python - 将序列从 FASTA 文件提取到多个文件,文件基于单独文件中的 header_ID

python - Django:在所有响应中强制使用 CSRF token

python - 如何访问作为 numpy 数组传递给 ctypes 回调的数组?