# 从前有座山,山上有座庙,庙里有个老和尚说:使用Python 包(package)组织代码 稍微正式一点的项目,都会通过将代码组织成有层次结构的组织,以便于管理和持续维护。Python 通过`包(package)`的方式来组织代码,包是一种特殊的`模块(module)`。 Python 的包有两种形式,分别是`Regular packages` 和 `namespace packages`。 所谓 `Regular packages` 就是指含有__init__.py的目录,这样的包被其他模块导入的时候,会先执行目录下`__init__.py`里的代码。`Regular packages` 可以嵌套,也就是目录下的子目录也可以是一个包。例如: ```python python_package_dir_example = ''' parent/ __init__.py one/ __init__.py one/ __init__.py two/ __init__.py three/ __init__.py ''' ``` 而 `namespace packages` 也是有层次结构的模块组织,不过它未必是存在文件夹里的,可以存在Zip压缩包里,也可以存在网络上,而且子包和父包也未必要存储在同一个地方。这里忽略不展开。 假设`parent/__init__.py` 里的代码是: ```python # -*- coding: UTF-8 -*- print('从前有座山,') ``` 假设`parent/one/__init__.py` 里的代码是: ```python # -*- coding: UTF-8 -*- print('山上有座庙,') ``` 假设`parent/one/one/__init__.py` 里的代码是: ```python # -*- coding: UTF-8 -*- print('庙里有个老和尚,') ``` 假设`parent/two/__init__.py` 里的代码是: ```python # -*- coding: UTF-8 -*- print('老和尚说:') ``` 假设`parent/three/__init__.py` 里的代码是: ```python # -*- coding: UTF-8 -*- print('从前有座山,') ``` 如果一个模块被`import`过,Python 会将导入的模块缓存在`sys.modules`字典里缓存起来,再次导入的时候不会重新执行导入动作,直接从缓存里取。反之,如果我们从`sys.modules`里把导入的模块删除,则再次`import`会再次触发模块导入动作。 利用以上知识,我们的目标是通过 `import` 语句导入模块,触发每个包目录下`__init__.py`加载时执行`print`语句,从而循环打印出: ```bash 从前有座山, 山上有座庙, 庙里有个老和尚, 老和尚说: 从前有座山, 山上有座庙, 庙里有个老和尚, 老和尚说: 从前有座山, ... ``` 以下导入模块的用法中,不能循环打印出上述绕口令的选项是? ## template ```python import sys if __name__ == '__main__': while True: import parent.one.one del sys.modules['parent.one.one'] import parent.one del sys.modules['parent.one'] import parent.two del sys.modules['parent.two'] import parent del sys.modules['parent'] ``` ## 答案 ```python import sys if __name__ == '__main__': while True: import parent import parent.one.one import parent.two del sys.modules['parent'] del sys.modules['parent.one.one'] del sys.modules['parent.two'] ``` ## 选项 ### A ```python import sys if __name__ == '__main__': while True: import parent.one.one del sys.modules['parent.one.one'] import parent.one del sys.modules['parent.one'] import parent.two del sys.modules['parent.two'] import parent del sys.modules['parent'] ``` ### B ```python import sys if __name__ == '__main__': while True: import parent.one.one import parent.two import parent.three del sys.modules['parent.one'] del sys.modules['parent.one.one'] del sys.modules['parent.two'] del sys.modules['parent.three'] ``` ### C ```python import sys if __name__ == '__main__': while True: import parent.one.one import parent.two import parent del sys.modules['parent.one'] del sys.modules['parent.one.one'] del sys.modules['parent.two'] del sys.modules['parent'] ``` ### D ```python import sys if __name__ == '__main__': while True: import parent import parent.one import parent.one.one import parent.two del sys.modules['parent'] del sys.modules['parent.one'] del sys.modules['parent.one.one'] del sys.modules['parent.two'] ``` ### E ```python import sys if __name__ == '__main__': while True: import parent.one.one import parent.two del sys.modules['parent'] del sys.modules['parent.one'] del sys.modules['parent.one.one'] del sys.modules['parent.two'] ```