将 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)