# 从前有座山，山上有座庙，庙里有个老和尚说：使用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
从前有座山，
山上有座庙，
庙里有个老和尚，
老和尚说：
从前有座山，
山上有座庙，
庙里有个老和尚，
老和尚说：
从前有座山，
...
```

以下导入模块的用法中，<span style="color:red">不能循环打印出</span>上述绕口令的选项是？

## 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']
```
