import_other_module.md 4.6 KB
Newer Older
F
feilong 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
# 从前有座山,山上有座庙,庙里有个老和尚说:使用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']
```