提交 0f3c5f28 编写于 作者: F feilong

改进9/10/11题

上级 0ccb896e
{ {
"export": [ "export": [
"import_json_example.json", "import_lib.json",
"import_other_module.json", "import_other_module.json",
"import_with_from.json" "import_with_from.json"
], ],
......
{
"one_line": {
"import json": [
"#include <json>;",
"using json;",
"import json;"
]
},
"source": "import_json_example.py",
"depends": [],
"exercise_id": 163,
"type": "code_options"
}
\ No newline at end of file
{
"source": "import_lib.md",
"depends": [],
"exercise_id": 163,
"type": "code_options"
}
\ No newline at end of file
# Python标准库模块导入
Python 语言通过`模块(module)`来组织代码。Python 标准库十分庞大,由C语言编写的内置模块,和由 Python 编写的解决常见开发需求的模块。下面的`Python数组`列举了常用标准库。
```python
python_modules = [
"os --- 多种操作系统接口",
"os.path --- 常用路径操作",
"re --- 正则表达式操作",
"datetime --- 基本日期和时间类型",
"heapq --- 堆队列算法",
"enum --- 对枚举的支持",
"math --- 数学函数",
"random --- 生成伪随机数",
"itertools --- 为高效循环而创建迭代器的函数",
"functools --- 高阶函数和可调用对象上的操作",
"shutil --- 高阶文件操作",
"sqlite3 --- SQLite 数据库 DB-API 2.0 接口模块",
"csv --- CSV 文件读写",
"hashlib --- 安全哈希与消息摘要",
"hmac --- 基于密钥的消息验证",
"time --- 时间的访问和转换",
"argparse --- 命令行选项、参数和子命令解析器",
"logging --- Python 的日志记录工具",
"threading --- 基于线程的并行",
"multiprocessing --- 基于进程的并行",
"socket --- 底层网络接口",
"email --- 电子邮件与 MIME 处理包",
"json --- JSON 编码和解码器",
"urllib --- URL 处理模块",
"http --- HTTP 模块"
]
```
使用 `import` 相关的语句可以引入 Python 标准库模块。特别地,`import` 可以被动态的从任何地方调用。
以下导入模块的用法中,<span style="color:red">错误</span>的选项是?
## template
```python
import json
from os import path
import datetime as dt
import time
if __name__ == '__main__':
obj = {
'err': 'success',
'result': ['item1', 'item2']
}
print(json.dumps(obj))
print(path.abspath('.'))
print(dt.datetime.now())
import math
print(math.ceil(1.3333))
print(time.time())
```
## 答案
```python
import time.time
if __name__ == '__main__':
print(time())
```
## 选项
### 使用 import 语句
```python
import json
if __name__ == '__main__':
obj = {'key': 'value'}
print(json.dumps(obj))
```
### 使用 from .. import .. 语句
```python
from os import path
if __name__ == '__main__':
print(path.abspath('.'))
```
### 使用 import .. as .. 语句
```python
import datetime as dt
if __name__ == '__main__':
print(dt.datetime.now())
```
### 动态导入
```python
if __name__ == '__main__':
import math
print(math.ceil(1.3333))
```
...@@ -5,6 +5,9 @@ ...@@ -5,6 +5,9 @@
import json import json
from os import path
import datetime as dt
import time
def dump_json(obj): def dump_json(obj):
...@@ -16,4 +19,13 @@ if __name__ == '__main__': ...@@ -16,4 +19,13 @@ if __name__ == '__main__':
'err': 'success', 'err': 'success',
'result': ['item1', 'item2'] 'result': ['item1', 'item2']
} }
dump_json(obj) print(json.dumps(obj))
print(path.abspath('.'))
print(dt.datetime.now())
import math
print(math.ceil(1.3333))
print(time.time())
{ {
"multiline": [ "source": "import_other_module.md",
{ "depends": [],
"import import_json_example": "import import_json_example.dump_json",
"import_json_example.dump_json": "dump_json"
},
{
"import_json_example.dump_json": "dump_json"
},
{
"import import_json_example": "import import_json_example;"
}
],
"source": "import_other_module.py",
"depends": [
"import_json_example.py"
],
"exercise_id": 164, "exercise_id": 164,
"type": "code_options" "type": "code_options"
} }
\ No newline at end of file
# 从前有座山,山上有座庙,庙里有个老和尚说:使用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']
```
...@@ -3,12 +3,18 @@ ...@@ -3,12 +3,18 @@
# 标题:Python 模块导入2 # 标题:Python 模块导入2
# 描述:通过 import 导入自己写的另外一个模块 # 描述:通过 import 导入自己写的另外一个模块
import import_json_example import sys
if __name__ == '__main__': if __name__ == '__main__':
obj = { while True:
'err': 'success', import parent.one.one
'result': ['item1', 'item2'] del sys.modules['parent.one.one']
}
import_json_example.dump_json(obj) import parent.one
del sys.modules['parent.one']
import parent.two
del sys.modules['parent.two']
import parent
del sys.modules['parent']
{
"source": "import_relative.py",
"depends": [],
"exercise_id": 165,
"type": "code_options"
}
\ No newline at end of file
# 使用相对路径导入包
良好的包/模块组织在程序开发中有重要的作用。随着项目代码的逐渐增加,一开始的单文件程序会逐渐膨胀,所幸 Python 提供当包模式可以良好应对通常的代码分层组织。
但是,当目录层次增加后,在下层目录里的代码引用其他目录的模块时,总是要输入全部路径有时并不方便,此时可以考虑使用 Python 的包相对路径来导入模块。
假设如下的`Python字符串`描述的包目录结构:
```python
relative_packages = '''
package/
__init__.py
subpackage1/
__init__.py
moduleX.py
moduleY.py
subpackage2/
__init__.py
moduleZ.py
moduleA.py
'''
```
假设:
* `package/subpackage1/moduleY.py` 里定义了函数 `spam`
* `package/subpackage2/moduleZ.py` 里定义了函数 `eggs`
* `package/moduleA.py` 里定义了函数 `foo`
以下选项都是在文件`package/subpackage1/moduleX.py`里导入模块的代码,请问<span style="color:red">错误</span>的选项是哪个?你知道为什么吗?
## template
```python
if __name__ == '__main__':
print(
'''
Absolute imports may use either the import <> or from <> import <> syntax, but relative imports may only use the second form; the reason for this is that:
```import XXX.YYY.ZZZ```
should expose `XXX.YYY.ZZZ` as a usable expression, but .moduleY is not a valid expression.
'''
)
```
## 答案
```python
import ..subpackage2.moduleZ
```
## 选项
### A
```python
from .moduleY import spam
```
### B
```python
from .moduleY import spam as ham
```
### C
```python
from . import moduleY
```
### D
```python
from ..subpackage1 import moduleY
```
### E
```python
from ..subpackage2.moduleZ import eggs
```
### F
```python
from ..moduleA import foo
```
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 模块导入3
# 描述:相对目录导入
if __name__ == '__main__':
print(
'''
Absolute imports may use either the import <> or from <> import <> syntax, but relative imports may only use the second form; the reason for this is that:
```import XXX.YYY.ZZZ```
should expose `XXX.YYY.ZZZ` as a usable expression, but .moduleY is not a valid expression.
'''
)
{
"multiline": [
{
"from import_json_example import dump_json": "from import_json_example import import_json_example",
"dump_json": "import_json_example.dump_json"
},
{
"from import_json_example import dump_json": "import dump_json from import_json_example"
},
{
"dump_json(obj)": "import_json_example.dump_json(obj)"
}
],
"source": "import_with_from.py",
"depends": [
"import_json_example.py"
],
"exercise_id": 165,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 模块导入3
# 描述:通过 from 语句导入模块
from import_json_example import dump_json
if __name__ == '__main__':
obj = {
'err': 'success',
'result': ['item1', 'item2']
}
dump_json(obj)
from .moduleY import spam
from .moduleY import spam as ham
from . import moduleY
from ..subpackage1 import moduleY
from ..subpackage2.moduleZ import eggs
from ..moduleA import foo
spam()
ham()
eggs()
foo()
# -*- coding: UTF-8 -*-
print('从前有座山,')
# -*- coding: UTF-8 -*-
print('庙里有个老和尚,')
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册