您习惯于在程序顶部看到导入语句,这意味着导入的模块在程序中的任何位置都可用。但是你也可以在函数内导入模块,这意味着导入的模块只能在函数内使用。如果你有一个只在一个函数中使用过的模块,这是一种让你的代码更加模块化的简单方法。
在功能级别导入模块的另一种替代方法是在模块级别(功能是其中的一部分)导入它。
既然模块是可重复使用的单元,那么前一个选项如何增加模块化?
您习惯于在程序顶部看到导入语句,这意味着导入的模块在程序中的任何位置都可用。但是你也可以在函数内导入模块,这意味着导入的模块只能在函数内使用。如果你有一个只在一个函数中使用过的模块,这是一种让你的代码更加模块化的简单方法。
在功能级别导入模块的另一种替代方法是在模块级别(功能是其中的一部分)导入它。
既然模块是可重复使用的单元,那么前一个选项如何增加模块化?
我不相信在功能级别导入更加模块化。从 Python 中的模块导入函数(或类)将解决库依赖关系,并且这些导入的函数无需导入相同的库即可工作。
(注意:我使用库来避免每隔一个词说模块)
例子:
我的模块.py
import sys
def printerr(message):
"""Use stderr for error messages"""
sys.stderr.write('{0}\n'.format(message))
sys.stderr.flush()
我的脚本.py
import os
from my_module import printerr
def main():
"""Derpy script"""
if 'my_important_file.txt' in os.listdir():
print("it's there")
else:
printerr("ERROR: Unable to find important file")
鉴于这是一个极其简化的示例,但在打印机中导入 sys 不会使其更加模块化。无论哪种方式,它都是同样模块化的。
以我的经验,当涉及到模块化时,可能并且确实出现的问题与技术债务的积累有关。
首先,您有一个简单的模块,它对它的功能有一个明确的概念。在该模块中导入的库是有意义的,并且在其中的函数/类中被高度使用。
随着时间的推移和功能的增加,我们通常只是在“最合适”的模块中添加新的函数/类(即“我想把它放在这里有意义吗?”)。
更多的时间过去了,一个更好的库开始流行,所以我会使用那个,但我真的不想花几个星期来替换所有旧代码(就像我有那样的时间,我有事情要做制作!)。
不久之后,你就会有一些粗糙的代码,可以导入大约 20 种东西,而且可以做很多事情。而且当然没有单元测试,所以每次你碰它,你都会破坏一些东西,但需要一周的时间才能发现......
现在你已经厌倦了处理这个问题,所以去死吧,我将在使用它的函数中导入我想要的东西;这比处理大约 20 次进口要容易。
一个非常有说服力的不导入函数的理由如下所示:
def doh():
import nothing
print "Homer says..."
这是您刚刚发布的一个错误,因为在您的单元测试中从未调用过 doh,但是它以一种您没有想到的奇怪方式被调用。“如果我像 PEP8 说的那样导入,我就不会遇到这个问题。”