将 python 模块导入例程或类定义有啥问题吗? [复制]

Posted

技术标签:

【中文标题】将 python 模块导入例程或类定义有啥问题吗? [复制]【英文标题】:Is there anything wrong with importing a python module into a routine or class definition? [duplicate]将 python 模块导入例程或类定义有什么问题吗? [复制] 【发布时间】:2011-10-28 08:53:27 【问题描述】:

可能重复:Should Python import statements always be at the top of a module?

我最近回复了SO question 并提供了这个例程作为解决方案:

def set_fontsize(fig,fontsize):
    import matplotlib
    """
    For each text object of a figure fig, set the font size to fontsize
    """
    if not isinstance(fig,matplotlib.figure.Figure):
        raise Exception("fig is not a matplotlib.figure.Figure")

    for textobj in fig.findobj(match=matplotlib.text.Text): 
        textobj.set_fontsize(fontsize)

我将 matplotlib 导入到 set_fontsize(fig,fontsize) 的定义中,因为不能保证使用此例程的人会在更全局的范围内导入 matplotlib(更好的术语?)。特别是因为许多 matplotlib 示例使用此导入调用例程:import matplotlib.pyplot as plt

是否存在我导入 matplotlib 会导致冲突的情况?

是否有任何效率成本?

是否有更好/更常见的替代方法来测试fig 是否是matplotlib.figure.Figure 的实例;不需要导入模块的替代方法?

【问题讨论】:

@carl,这个问题及其答案几乎涵盖了我的问题。 【参考方案1】:

导入内部函数和类没有任何问题 - 例如,这是一种处理相互递归导入(两个文件相互导入另一个文件)的有用方法。

然而,检查参数的类型有问题。惯用的 python 会检查无花果的类型。相反,只要让误用失败,它就会失败。这是因为你打破了“鸭子打字”——人们不能用“像”无花果一样工作的对象来调用你的例程,即使他们想这样做(一个明显的例子是测试模拟;另一个例子是有人写了一个 matplotlib 的替代品,它有相同的 API,但外观或效果更好)。

因此,对于您那里的代码,根本不需要导入。只需使用fig

更一般地说,导入在第一次使用时会被缓存,因此您通常不需要担心效率(我并不是说它是完美的,但这是您在担心之前需要先分析的那种事情)。

【讨论】:

感谢您解释为什么不检查参数的类型。我想我仍然需要在某个地方导入,以便调用需要知道 matplotlib.text.Text 的 findobj。 这可能无关紧要,但我找到了解决此问题的方法。我可以通过检查__module__ 的值来查看 fig 的每个子项是否位于“matplotlib.text”模块中。我根本不需要导入,但是您的回答非常有用。谢谢。【参考方案2】:

在函数内部导入并没有什么特别的错误——尽管你应该在文档字符串之后执行它,否则 Python 将看不到文档字符串——但你的推理没有任何意义。

如果您在模块级别导入,并且有人导入了您的函数,则该函数可以访问其模块中的所有内容,包括导入。您的函数的用户不需要专门导入任何内容。

【讨论】:

以上是关于将 python 模块导入例程或类定义有啥问题吗? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

如何将令人烦恼的“for”循环转换为“Object.keys”例程或类似程序(JSLint)

Python调用自定义模块方法有啥

导入整个模块与仅从 python 中的模块导入所需的方法有啥区别? [复制]

有没有人为 Keycloak 制作了导入功能?

有啥方法可以导入带有自定义指令的查询吗?

有长度单位的 C#/.NET 内置转换例程吗?