-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path4.scripting.md
More file actions
527 lines (411 loc) · 18 KB
/
4.scripting.md
File metadata and controls
527 lines (411 loc) · 18 KB
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
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
Python 中的脚本编写
---
### 概述
- Python 安装和环境设置
- 运行和修改 Python 脚本
- 与用户输入交互
- 处理异常
- 读写文件
- 导入本地、标准和第三方模块
- 在解释器中进行实验
---
### 在脚本中接受原始输入
- 使用内置函数 `input` 获取用户的原始输入, 该函数接受一个可选字符串参数,用于指定在要求用户输入时向用户显示的消息。
```Python
name = input("Enter your name: ")
print("Hello there, {}!".format(name.title()))
```
* 这段代码提示用户输入姓名,然后在问候语中使用该输入。input 函数获取用户输入的任何内容并将其存储为字符串。
- 将输入解析为字符串之外的其他类型,例如整数(如以下示例所示),需要用新的类型封装结果并从字符串转换为该类型。
```Python
num = int(input("Enter an integer"))
print("hello" * num)
```
- 我们还可以使用内置函数 eval 将用户输入解析为 Python 表达式。该函数会将字符串评估为一行 Python 代码。
```python
result = eval(input("Enter an expression: "))
print(result)
```
* 如果用户输入 `2 * 3`,输出为 `6`。
### 错误和异常
- 当 Python 无法解析代码时,就会发生`语法错误`,因为我们没有遵守正确的 Python 语法。
- 当在程序执行期间出现意外情况时,就会发生`异常`,即使代码在语法上正确无误。Python 有不同类型的内置异常。
### 指定异常
- 可以指定要在 `except` 块中处理哪个错误,如下所示:
```python
try:
# some code
except ValueError:
# some code
```
- 现在它会捕获 `ValueError` 异常,但是不会捕获其他异常。如果我们希望该处理程序处理多种异常,我们可以在 `except` 后面添加异常元组。
```python
try:
# some code
except (ValueError, KeyboardInterrupt):
# some code
```
- 或者,如果我们希望根据异常执行不同的代码块,可以添加多个 `except` 块。
```python
try:
# some code
except ValueError:
# some code
except KeyboardInterrupt:
# some code
```
- 处理除以零的案例:
```python
def create_groups(items, num_groups):
try:
size = len(items) // num_groups
except ZeroDivisionError:
print("WARNING: Returning empty list. Please use a nonzero number.")
return []
else:
groups = []
for i in range(0, len(items), size):
groups.append(items[i:i + size])
return groups
finally:
print("{} groups returned.".format(num_groups))
print("Creating 6 groups...")
for group in create_groups(range(32), 6):
print(list(group))
print("\nCreating 0 groups...")
for group in create_groups(range(32), 0):
print(list(group))
```
正确的输出应该是:
```log
Creating 6 groups...
6 groups returned.
[0, 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]
Creating 0 groups...
WARNING: Returning empty list. Please use a nonzero number.
0 groups returned.
```
### 访问错误消息
- 在处理异常时,依然可以如下所示地访问其错误消息:
```python
try:
# some code
except ZeroDivisionError as e:
# some code
print("ZeroDivisionError occurred: {}".format(e))
```
应该会输出如下所示的结果:
```log
ZeroDivisionError occurred: division by zero
```
- 如果没有要处理的具体错误,依然可以如下所示地访问消息:
```python
try:
# some code
except Exception as e:
# some code
print("Exception occurred: {}".format(e))
```
此处:`Exception` 是所有内置异常的基础类。
### 读写文件
- 读取文件
```python
f = open('my_path/my_file.txt', 'r') # open方法会返回文件对象
file_data = f.read() # 通过read方法获取数据
f.close() # 关闭该文件
```
* 首先使用内置函数 `open` 打开文件。需要文件路径字符串。`open` 函数会返回文件对象,它是一个 Python 对象,Python 通过该对象与文件本身交互。在此示例中,我们将此对象赋值给变量 `f`。
* 你可以在 open 函数中指定可选参数。参数之一是打开文件时采用的模式。在此示例中,我们使用 r,即只读模式。这实际上是模式参数的默认值。
* 使用 `read` 访问文件对象的内容。该 `read` 方法会接受文件中包含的文本并放入字符串中。在此示例中,我们将该方法返回的字符串赋值给变量 `file_data`。
* 当我们处理完文件后,使用 `close` 方法释放该文件占用的系统资源。
- 写入文件
```python
f = open('my_path/my_file.txt', 'w')
f.write("Hello there!")
f.close()
```
* 以写入 ('w') 模式打开文件。如果文件不存在,Python 将为你创建一个文件。如果以写入模式打开现有文件,该文件中之前包含的所有内容将被删除。如果你打算向现有文件添加内容,但是不删除其中的内容,可以使用附加 ('a') 模式,而不是写入模式。
* 使用 `write` 方法向文件中添加文本。
* 操作完毕后,关闭文件。
- `with`语法,该语法会在你使用完文件后自动关闭该文件
```python
with open('my_path/my_file.txt', 'r') as f:
file_data = f.read()
```
* 该 `with` 关键字使你能够打开文件,对文件执行操作,并在缩进代码(在此示例中是读取文件)执行之后自动关闭文件。现在,我们不需要调用 `f.close()` 了!
* 只能在此缩进块中访问文件对象 `f`。
- 在之前的代码中,`f.read()` 调用没有传入参数。它自动变成从当前位置读取文件的所有剩余内容,即整个文件。如果向 .read() 传入整型参数,它将读取长度是这么多字符的内容,输出所有内容,并使 'window' 保持在该位置以准备继续读取。
```python
with open(camelot.txt) as song:
print(song.read(2))
print(song.read(8))
print(song.read())
```
输出:
```log
We
're the
knights of the round table
We dance whenever we're able
```
- 读取文件下一行的方法: `f.readlines()`
- Python 将使用语法 `for line in file` 循环访问文件中的各行内容。 我可以使用该语法创建列表中的行列表。因为每行依然包含换行符,因此我使用 `.strip()` 删掉换行符。
```python
camelot_lines = []
with open("camelot.txt") as f:
for line in f:
camelot_lines.append(line.strip())
print(camelot_lines) # ["We're the knights of the round table", "We dance whenever we're able"]
```
- 相关练习:你将创建一个演员名单,列出参演电视剧《巨蟒剧团之飞翔的马戏团》的演员。写一个叫做 `create_cast_list` 的函数,该函数会接受文件名作为输入,并返回演员姓名列表。 它将运行文件 `flying_circus_cast.txt`。文件的每行包含演员姓名、逗号,以及关于节目角色的一些(凌乱)信息。你只需提取姓名,并添加到列表中。你可以使用 `.split()` 方法处理每行。
解决方案:
```python
def create_cast_list(filename):
cast_list = []
#use with to open the file filename
#use the for loop syntax to process each line
#and add the actor name to cast_list
with open(filename) as f:
# use the for loop syntax to process each line
# and add the actor name to cast_list
for line in f:
line_data = line.split(',')
cast_list.append(line_data[0])
return cast_list
cast_list = create_cast_list('./txts/flying_circus_cast.txt')
for actor in cast_list:
print(actor)
```
### 导入本地脚本
- `import` 如果你要导入的 Python 脚本与当前脚本位于同一个目录下,只需输入 import,然后是文件名,无需扩展名 .py。 伪代码如下:
```python
import useful_functions
useful_functions.add_five([1, 2, 3, 4])
```
- 我们可以为导入模块添加别名,以使用不同的名称引用它。
```python
import useful_functions as uf
uf.add_five([1, 2, 3, 4])
```
- 使用 `if main` 块
* 为了避免运行从其他脚本中作为模块导入的脚本中的可执行语句,将这些行包含在 `if __name__ == "__main__"` 块中。或者,将它们包含在函数 `main()` 中并在 `if main` 块中调用该函数。
* 每当我们运行此类脚本时,Python 实际上会为所有模块设置一个特殊的内置变量 `__name__`。当我们运行脚本时,Python 会将此模块识别为主程序,并将此模块的 `__name__` 变量设为字符串 "__main__"。对于该脚本中导入的任何模块,这个内置 `__name__` 变量会设为该模块的名称。因此,条件 `if __name__ == "__main__"`会检查该模块是否为主程序。
- 在同一目录下创建如下两个脚本文件,并在终端里运行这些脚本!实验 `if main` 块并访问导入模块中的对象!
demo.py 文件
```python
# demo.py
import useful_functions as uf
scores = [88, 92, 79, 93, 85]
mean = uf.mean(scores)
curved = uf.add_five(scores)
mean_c = uf.mean(curved)
print("Scores:", scores)
print("Original Mean:", mean, " New Mean:", mean_c)
print(__name__)
print(uf.__name__)
```
useful_functions.py文件
```python
# useful_functions.py
def mean(num_list):
return sum(num_list) / len(num_list)
def add_five(num_list):
return [n + 5 for n in num_list]
def main():
print("Testing mean function")
n_list = [34, 44, 23, 46, 12, 24]
correct_mean = 30.5
assert(mean(n_list) == correct_mean)
print("Testing add_five function")
correct_list = [39, 49, 28, 51, 17, 29]
assert(add_five(n_list) == correct_list)
print("All tests passed!")
if __name__ == '__main__':
main()
```
如果运行 $ `python demo.py`,那么有如下输出结果:
```log
Scores: [88, 92, 79, 93, 85]
Original Mean: 87.4 New Mean: 92.4
__main__
useful_functions
```
如果运行 $ `python useful_functions.py`,那么有如下输出结果:
```log
Testing mean function
Testing add_five function
All tests passed!
```
### import 导入模块的技巧
- 要从模块中导入单个函数或类:
```python
from module_name import object_name
```
- 要从模块中导入多个单个对象:
```python
from module_name import first_object, second_object
```
- 要重命名模块:
```python
import module_name as new_name
```
- 要从模块中导入对象并重命名:
```python
from module_name import object_name as new_name
```
- 要从模块中单个地导入所有对象(请勿这么做):
```python
from module_name import *
```
- 如果你真的想使用模块中的所有对象,请使用标准导入 module_name 语句并使用点记法访问每个对象
```python
import module_name
```
- 为了更好地管理代码,Standard 标准库中的模块被拆分成了子模块并包含在软件包中。软件包是一个包含子模块的模块。子模块使用普通的点记法指定。子模块的指定方式是软件包名称、点,然后是子模块名称。你可以如下所示地导入子模块
```python
import package_name.submodule_name
```
### Python 中常用的标准库
- 使用 `math` 模块,计算 `e` 的3次幂,然后 输出 答案
```python
import math
print(math.exp(3)) # 20.085536923187668
```
- 写一个叫做 `generate_password` 的函数,该函数会从提供的单词文件中随机选择三个单词,并将它们连接成一个字符串。我们已经在起始代码中提供了从文件中读取数据的代码,你需要利用这些部分构建一个密码。
words.txt:
```txt
Alice
was
beginning
to
get
very
tired
of
sitting
by
her
sister
bank
having
nothing
Once
twice
she
had
peeped
into
the
book
her
sister
was
reading
but
it
had
no
pictures
or
conversations
in
it
and
what
is
the
use
of
a
book
thought
Alice
without
pictures
or
conversations
```
password_generator.py :
```python
# Use an import statement at the top
import random
word_file = "words.txt"
word_list = []
#fill up the word_list
with open(word_file,'r') as words:
for line in words:
# remove white space and make everything lowercase
word = line.strip().lower()
# don't include words that are too long or too short
if 3 < len(word) < 8:
word_list.append(word)
# Add your function generate_password here
# It should return a string consisting of three random words
# concatenated together without spaces
def generate_password() :
return random.choice(word_list) + random.choice(word_list) + random.choice(word_list)
# test your function
print(generate_password())
```
运行 $ `python password_generator.py`, 随机输出三个单词连成的字符串
- python中获取当前时间和日期的模块: `datetime`
- python中具有更改当前工作目录的方法 `os`
- 哪个模块可以将逗号分隔 (.csv) 文件中的每行数据读取到 Python 中? `csv`
- 哪个模块可以帮助我们从 zip 文件中提取所有文件? `zipfile`
- 哪个模块可以显示代码的运行时间? `time`
### Python 中常用的模块
- `csv`:对于读取 csv 文件来说非常便利
- `collections`:常见数据类型的实用扩展,包括 OrderedDict、defaultdict 和 namedtuple
- `random`:生成假随机数字,随机打乱序列并选择随机项
- `string`:关于字符串的更多函数。此模块还包括实用的字母集合,例如 string.digits(包含所有字符都是有效数字的字符串)。
- `re`:通过正则表达式在字符串中进行模式匹配
- `math`:一些标准数学函数
- `os`:与操作系统交互
- `os.path`:os 的子模块,用于操纵路径名称
- `sys`:直接使用 Python 解释器
- `json`:适用于读写 json 文件(面向网络开发)
### Python 中的第三方库
- 独立开发者编写了成千上万的第三方库!你可以使用 `pip` 安装这些库。`pip` 是在 Python 3 中包含的软件包管理器,它是标准 Python 软件包管理器,但并不是唯一的管理器。另一个热门的管理器是 `Anaconda`,该管理器专门针对数据科学。
- 要使用 `pip` 安装软件包,在命令行中输入`pip install`,然后是软件包名称,如下所示:`pip install package_name`。该命令会下载并安装该软件包,以便导入你的程序中。安装完毕后,你可以使用从标准库中导入模块时用到的相同语法导入第三方软件包。
### 使用 `requirements.txt` 文件
- 大型 Python 程序可能依赖于十几个第三方软件包。为了更轻松地分享这些程序,程序员经常会在叫做 requirements.txt 的文件中列出项目的依赖项。下面是一个 requirements.txt 文件示例。
```txt
beautifulsoup4==4.5.1
bs4==0.0.1
pytz==2016.7
requests==2.11.1
```
- 该文件的每行包含软件包名称和版本号。版本号是可选项,但是通常都会包含。不同版本的库之间可能变化不大,可能截然不同,因此有必要使用程序作者在写程序时用到的库版本。
- 你可以使用 `pip` 一次性安装项目的所有依赖项,方法是在命令行中输入 `pip install -r requirements.txt`
### 实用的第三方软件包
- [IPython](https://ipython.org/) - 更好的交互式 Python 解释器
- [requests](http://docs.python-requests.org/) - 提供易于使用的方法来发出网络请求。适用于访问网络 API。
- [Flask](http://flask.pocoo.org/) - 一个小型框架,用于构建网络应用和 API。
- [Django](https://www.djangoproject.com/) - 一个功能更丰富的网络应用构建框架。Django 尤其适合设计复杂、内容丰富的网络应用。
- [Beautiful Soup](https://www.crummy.com/software/BeautifulSoup/) - 用于解析 HTML 并从中提取信息。适合网页数据抽取。
- [pytest](http://doc.pytest.org/) - 扩展了 Python 的内置断言,并且是最具单元性的模块。
- [PyYAML](http://pyyaml.org/wiki/PyYAML) - 用于读写 YAML 文件。
- [NumPy](http://www.numpy.org/) - 用于使用 Python 进行科学计算的最基本软件包。它包含一个强大的 N 维数组对象和实用的线性代数功能等。
- [pandas](http://pandas.pydata.org/) - 包含高性能、数据结构和数据分析工具的库。尤其是,pandas 提供 dataframe!
- [matplotlib](http://matplotlib.org/) - 二维绘制库,会生成达到发布标准的高品质图片,并且采用各种硬拷贝格式和交互式环境。
- [ggplot](http://ggplot.yhathq.com/) - 另一种二维绘制库,基于 R's ggplot2 库。
- [Pillow](https://python-pillow.org/) - Python 图片库可以向你的 Python 解释器添加图片处理功能。
- [pyglet](http://www.pyglet.org/) - 专门面向游戏开发的跨平台应用框架。
- [Pygame](http://www.pygame.org/) - 用于编写游戏的一系列 Python 模块。
- [pytz](http://pytz.sourceforge.net/) - Python 的世界时区定义。
### 学习链接
- https://docs.python.org/3/tutorial/
- https://docs.python.org/3/library/exceptions.html#bltin-exceptions
- https://docs.python.org/3/tutorial/inputoutput.html#reading-and-writing-files
- https://pymotw.com/3/
- https://docs.python.org/3.6/library/math.html?highlight=math%20module#module-math
- https://docs.python.org/3/library/
- https://docs.python.org/3/index.html
- https://doughellmann.com/blog/
- https://eli.thegreenplace.net/