Merge branch 'jackfrued:master' into master
|
@ -10,7 +10,7 @@
|
||||||
4. 2000年10月16日:Python 2.0发布,增加了完整的[垃圾回收](https://zh.wikipedia.org/wiki/%E5%9E%83%E5%9C%BE%E5%9B%9E%E6%94%B6_(%E8%A8%88%E7%AE%97%E6%A9%9F%E7%A7%91%E5%AD%B8)),提供了对[Unicode](https://zh.wikipedia.org/wiki/Unicode)的支持。与此同时,Python的整个开发过程更加透明,社区对开发进度的影响逐渐扩大,生态圈开始慢慢形成。
|
4. 2000年10月16日:Python 2.0发布,增加了完整的[垃圾回收](https://zh.wikipedia.org/wiki/%E5%9E%83%E5%9C%BE%E5%9B%9E%E6%94%B6_(%E8%A8%88%E7%AE%97%E6%A9%9F%E7%A7%91%E5%AD%B8)),提供了对[Unicode](https://zh.wikipedia.org/wiki/Unicode)的支持。与此同时,Python的整个开发过程更加透明,社区对开发进度的影响逐渐扩大,生态圈开始慢慢形成。
|
||||||
5. 2008年12月3日:Python 3.0发布,它并不完全兼容之前的Python代码,不过因为目前还有不少公司在项目和运维中使用Python 2.x版本,所以Python 3.x的很多新特性后来也被移植到Python 2.6/2.7版本中。
|
5. 2008年12月3日:Python 3.0发布,它并不完全兼容之前的Python代码,不过因为目前还有不少公司在项目和运维中使用Python 2.x版本,所以Python 3.x的很多新特性后来也被移植到Python 2.6/2.7版本中。
|
||||||
|
|
||||||
目前我们使用的Python 3.7.x的版本是在2018年发布的,Python的版本号分为三段,形如A.B.C。其中A表示大版本号,一般当整体重写,或出现不向后兼容的改变时,增加A;B表示功能更新,出现新功能时增加B;C表示小的改动(例如:修复了某个Bug),只要有修改就增加C。如果对Python的历史感兴趣,可以阅读名为[《Python简史》](http://www.cnblogs.com/vamei/archive/2013/02/06/2892628.html)的网络文章。
|
目前我使用的Python 3.7.x的版本是在2018年发布的,Python的版本号分为三段,形如A.B.C。其中A表示大版本号,一般当整体重写,或出现不向后兼容的改变时,增加A;B表示功能更新,出现新功能时增加B;C表示小的改动(例如:修复了某个Bug),只要有修改就增加C。如果对Python的历史感兴趣,可以阅读名为[《Python简史》](http://www.cnblogs.com/vamei/archive/2013/02/06/2892628.html)的网络文章。
|
||||||
|
|
||||||
#### Python的优缺点
|
#### Python的优缺点
|
||||||
|
|
||||||
|
@ -218,7 +218,7 @@ pip3 install ipython
|
||||||
|
|
||||||
#### PyCharm - Python开发神器
|
#### PyCharm - Python开发神器
|
||||||
|
|
||||||
PyCharm的安装、配置和使用在[《玩转PyCharm》](../玩转PyCharm.md)进行了介绍,有兴趣的读者可以选择阅读。
|
PyCharm的安装、配置和使用在[《玩转PyCharm》](../番外篇/玩转PyCharm.md)进行了介绍,有兴趣的读者可以选择阅读。
|
||||||
|
|
||||||
![](./res/python-pycharm.png)
|
![](./res/python-pycharm.png)
|
||||||
|
|
||||||
|
|
|
@ -193,7 +193,7 @@ c = (f - 32) / 1.8
|
||||||
print('%.1f华氏度 = %.1f摄氏度' % (f, c))
|
print('%.1f华氏度 = %.1f摄氏度' % (f, c))
|
||||||
```
|
```
|
||||||
|
|
||||||
> **说明**:在使用`print`函数输出时,也可以对字符串内容进行格式化处理,上面`print`函数中的字符串`%1.f`是一个占位符,稍后会由一个`float`类型的变量值替换掉它。同理,如果字符串中有`%d`,后面可以用一个`int`类型的变量值替换掉它,而`%s`会被字符串的值替换掉。除了这种格式化字符串的方式外,还可以用下面的方式来格式化字符串,其中`{f:.1f}`和`{c:.1f}`可以先看成是`{f}`和`{c}`,表示输出时会用变量`f`和变量`c`的值替换掉这两个占位符,后面的`:.1f`表示这是一个浮点数,小数点后保留1位有效数字。
|
> **说明**:在使用`print`函数输出时,也可以对字符串内容进行格式化处理,上面`print`函数中的字符串`%.1f`是一个占位符,稍后会由一个`float`类型的变量值替换掉它。同理,如果字符串中有`%d`,后面可以用一个`int`类型的变量值替换掉它,而`%s`会被字符串的值替换掉。除了这种格式化字符串的方式外,还可以用下面的方式来格式化字符串,其中`{f:.1f}`和`{c:.1f}`可以先看成是`{f}`和`{c}`,表示输出时会用变量`f`和变量`c`的值替换掉这两个占位符,后面的`:.1f`表示这是一个浮点数,小数点后保留1位有效数字。
|
||||||
>
|
>
|
||||||
> ```Python
|
> ```Python
|
||||||
> print(f'{f:.1f}华氏度 = {c:.1f}摄氏度')
|
> print(f'{f:.1f}华氏度 = {c:.1f}摄氏度')
|
||||||
|
|
|
@ -200,7 +200,7 @@ from module1 import foo
|
||||||
foo()
|
foo()
|
||||||
```
|
```
|
||||||
|
|
||||||
需要说明的是,如果我们导入的模块除了定义函数之外还中有可以执行代码,那么Python解释器在导入这个模块时就会执行这些代码,事实上我们可能并不希望如此,因此如果我们在模块中编写了执行代码,最好是将这些执行代码放入如下所示的条件中,这样的话除非直接运行该模块,if条件下的这些代码是不会执行的,因为只有直接执行的模块的名字才是"\_\_main\_\_"。
|
需要说明的是,如果我们导入的模块除了定义函数之外还有可以执行代码,那么Python解释器在导入这个模块时就会执行这些代码,事实上我们可能并不希望如此,因此如果我们在模块中编写了执行代码,最好是将这些执行代码放入如下所示的条件中,这样的话除非直接运行该模块,if条件下的这些代码是不会执行的,因为只有直接执行的模块的名字才是"\_\_main\_\_"。
|
||||||
|
|
||||||
`module3.py`
|
`module3.py`
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
### 使用字符串
|
### 使用字符串
|
||||||
|
|
||||||
第二次世界大战促使了现代电子计算机的诞生,最初计算机被应用于导弹弹道的计算,而在计算机诞生后的很多年时间里,计算机处理的信息基本上都是数值型的信息。世界上的第一台电子计算机叫ENIAC(电子数值积分计算机),诞生于美国的宾夕法尼亚大学,每秒钟能够完成约5000次浮点运算。随着时间的推移,虽然数值运算仍然是计算机日常工作中最为重要的事情之一,但是今天的计算机处理得更多的数据可能都是以文本的方式存在的,如果我们希望通过Python程序操作本这些文本信息,就必须要先了解字符串类型以及与它相关的知识。
|
第二次世界大战促使了现代电子计算机的诞生,最初计算机被应用于导弹弹道的计算,而在计算机诞生后的很多年时间里,计算机处理的信息基本上都是数值型的信息。世界上的第一台电子计算机叫ENIAC(电子数值积分计算机),诞生于美国的宾夕法尼亚大学,每秒钟能够完成约5000次浮点运算。随着时间的推移,虽然数值运算仍然是计算机日常工作中最为重要的事情之一,但是今天的计算机处理得更多的数据可能都是以文本的方式存在的,如果我们希望通过Python程序操作这些文本信息,就必须要先了解字符串类型以及与它相关的知识。
|
||||||
|
|
||||||
所谓**字符串**,就是由零个或多个字符组成的有限序列,一般记为![$${\displaystyle s=a_{1}a_{2}\dots a_{n}(0\leq n \leq \infty)}$$](./res/formula_5.png)。在Python程序中,如果我们把单个或多个字符用单引号或者双引号包围起来,就可以表示一个字符串。
|
所谓**字符串**,就是由零个或多个字符组成的有限序列,一般记为![$${\displaystyle s=a_{1}a_{2}\dots a_{n}(0\leq n \leq \infty)}$$](./res/formula_5.png)。在Python程序中,如果我们把单个或多个字符用单引号或者双引号包围起来,就可以表示一个字符串。
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
| \| | 分支 | foo\|bar | 可以匹配foo或者bar |
|
| \| | 分支 | foo\|bar | 可以匹配foo或者bar |
|
||||||
| (?#) | 注释 | | |
|
| (?#) | 注释 | | |
|
||||||
| (exp) | 匹配exp并捕获到自动命名的组中 | | |
|
| (exp) | 匹配exp并捕获到自动命名的组中 | | |
|
||||||
| (? <name>exp) | 匹配exp并捕获到名为name的组中 | | |
|
| (?<name>exp) | 匹配exp并捕获到名为name的组中 | | |
|
||||||
| (?:exp) | 匹配exp但是不捕获匹配的文本 | | |
|
| (?:exp) | 匹配exp但是不捕获匹配的文本 | | |
|
||||||
| (?=exp) | 匹配exp前面的位置 | \\b\\w+(?=ing) | 可以匹配I'm dancing中的danc |
|
| (?=exp) | 匹配exp前面的位置 | \\b\\w+(?=ing) | 可以匹配I'm dancing中的danc |
|
||||||
| (?<=exp) | 匹配exp后面的位置 | (?<=\\bdanc)\\w+\\b | 可以匹配I love dancing and reading中的第一个ing |
|
| (?<=exp) | 匹配exp后面的位置 | (?<=\\bdanc)\\w+\\b | 可以匹配I love dancing and reading中的第一个ing |
|
||||||
|
|
|
@ -316,7 +316,7 @@ if __name__ == '__main__':
|
||||||
|
|
||||||
但是,切换作业是有代价的,比如从语文切到数学,要先收拾桌子上的语文书本、钢笔(这叫保存现场),然后,打开数学课本、找出圆规直尺(这叫准备新环境),才能开始做数学作业。操作系统在切换进程或者线程时也是一样的,它需要先保存当前执行的现场环境(CPU寄存器状态、内存页等),然后,把新任务的执行环境准备好(恢复上次的寄存器状态,切换内存页等),才能开始执行。这个切换过程虽然很快,但是也需要耗费时间。如果有几千个任务同时进行,操作系统可能就主要忙着切换任务,根本没有多少时间去执行任务了,这种情况最常见的就是硬盘狂响,点窗口无反应,系统处于假死状态。所以,多任务一旦多到一个限度,反而会使得系统性能急剧下降,最终导致所有任务都做不好。
|
但是,切换作业是有代价的,比如从语文切到数学,要先收拾桌子上的语文书本、钢笔(这叫保存现场),然后,打开数学课本、找出圆规直尺(这叫准备新环境),才能开始做数学作业。操作系统在切换进程或者线程时也是一样的,它需要先保存当前执行的现场环境(CPU寄存器状态、内存页等),然后,把新任务的执行环境准备好(恢复上次的寄存器状态,切换内存页等),才能开始执行。这个切换过程虽然很快,但是也需要耗费时间。如果有几千个任务同时进行,操作系统可能就主要忙着切换任务,根本没有多少时间去执行任务了,这种情况最常见的就是硬盘狂响,点窗口无反应,系统处于假死状态。所以,多任务一旦多到一个限度,反而会使得系统性能急剧下降,最终导致所有任务都做不好。
|
||||||
|
|
||||||
是否采用多任务的第二个考虑是任务的类型,可以把任务分为计算密集型和I/O密集型。计算密集型任务的特点是要进行大量的计算,消耗CPU资源,比如对视频进行编码解码或者格式转换等等,这种任务全靠CPU的运算能力,虽然也可以用多任务完成,但是任务越多,花在任务切换的时间就越多,CPU执行任务的效率就越低。计算密集型任务由于主要消耗CPU资源,这类任务用Python这样的脚本语言去执行效率通常很低,最能胜任这类任务的是C语言,我们之前提到了Python中有嵌入C/C++代码的机制。
|
是否采用多任务的第二个考虑是任务的类型,可以把任务分为计算密集型和I/O密集型。计算密集型任务的特点是要进行大量的计算,消耗CPU资源,比如对视频进行编码解码或者格式转换等等,这种任务全靠CPU的运算能力,虽然也可以用多任务完成,但是任务越多,花在任务切换的时间就越多,CPU执行任务的效率就越低。计算密集型任务由于主要消耗CPU资源,这类任务用Python这样的脚本语言去执行效率通常很低,最能胜任这类任务的是C语言,我们之前提到过Python中有嵌入C/C++代码的机制。
|
||||||
|
|
||||||
除了计算密集型任务,其他的涉及到网络、存储介质I/O的任务都可以视为I/O密集型任务,这类任务的特点是CPU消耗很少,任务的大部分时间都在等待I/O操作完成(因为I/O的速度远远低于CPU和内存的速度)。对于I/O密集型任务,如果启动多任务,就可以减少I/O等待时间从而让CPU高效率的运转。有一大类的任务都属于I/O密集型任务,这其中包括了我们很快会涉及到的网络应用和Web应用。
|
除了计算密集型任务,其他的涉及到网络、存储介质I/O的任务都可以视为I/O密集型任务,这类任务的特点是CPU消耗很少,任务的大部分时间都在等待I/O操作完成(因为I/O的速度远远低于CPU和内存的速度)。对于I/O密集型任务,如果启动多任务,就可以减少I/O等待时间从而让CPU高效率的运转。有一大类的任务都属于I/O密集型任务,这其中包括了我们很快会涉及到的网络应用和Web应用。
|
||||||
|
|
||||||
|
@ -324,9 +324,9 @@ if __name__ == '__main__':
|
||||||
|
|
||||||
### 单线程+异步I/O
|
### 单线程+异步I/O
|
||||||
|
|
||||||
现代操作系统对I/O操作的改进中最为重要的就是支持异步I/O。如果充分利用操作系统提供的异步I/O支持,就可以用单进程单线程模型来执行多任务,这种全新的模型称为事件驱动模型。Nginx就是支持异步I/O的Web服务器,它在单核CPU上采用单进程模型就可以高效地支持多任务。在多核CPU上,可以运行多个进程(数量与CPU核心数相同),充分利用多核CPU。用Node.js开发的服务器端程序也使用了这种工作模式,这也是当下实现多任务编程的一种趋势。
|
现代操作系统对I/O操作的改进中最为重要的就是支持异步I/O。如果充分利用操作系统提供的异步I/O支持,就可以用单进程单线程模型来执行多任务,这种全新的模型称为事件驱动模型。Nginx就是支持异步I/O的Web服务器,它在单核CPU上采用单进程模型就可以高效地支持多任务。在多核CPU上,可以运行多个进程(数量与CPU核心数相同),充分利用多核CPU。用Node.js开发的服务器端程序也使用了这种工作模式,这也是当下并发编程的一种流行方案。
|
||||||
|
|
||||||
在Python语言中,单线程+异步I/O的编程模型称为协程,有了协程的支持,就可以基于事件驱动编写高效的多任务程序。协程最大的优势就是极高的执行效率,因为子程序切换不是线程切换,而是由程序自身控制,因此,没有线程切换的开销。协程的第二个优势就是不需要多线程的锁机制,因为只有一个线程,也不存在同时写变量冲突,在协程中控制共享资源不用加锁,只需要判断状态就好了,所以执行效率比多线程高很多。如果想要充分利用CPU的多核特性,最简单的方法是多进程+协程,既充分利用多核,又充分发挥协程的高效率,可获得极高的性能。关于这方面的内容,我稍后会做一个专题来进行讲解。
|
在Python语言中,单线程+异步I/O的编程模型称为协程,有了协程的支持,就可以基于事件驱动编写高效的多任务程序。协程最大的优势就是极高的执行效率,因为子程序切换不是线程切换,而是由程序自身控制,因此,没有线程切换的开销。协程的第二个优势就是不需要多线程的锁机制,因为只有一个线程,也不存在同时写变量冲突,在协程中控制共享资源不用加锁,只需要判断状态就好了,所以执行效率比多线程高很多。如果想要充分利用CPU的多核特性,最简单的方法是多进程+协程,既充分利用多核,又充分发挥协程的高效率,可获得极高的性能。关于这方面的内容,在后续的课程中会进行讲解。
|
||||||
|
|
||||||
### 应用案例
|
### 应用案例
|
||||||
|
|
||||||
|
|
|
@ -110,13 +110,70 @@ Pillow中最为重要的是Image类,读取和处理图像都要通过这个类
|
||||||
|
|
||||||
### 处理Excel电子表格
|
### 处理Excel电子表格
|
||||||
|
|
||||||
Python的openpyxl模块让我们可以在Python程序中读取和修改Excel电子表格,当然实际工作中,我们可能会用LibreOffice Calc和OpenOffice Calc来处理Excel的电子表格文件,这就意味着openpyxl模块也能处理来自这些软件生成的电子表格。关于openpyxl的使用手册和使用文档可以查看它的[官方文档](https://openpyxl.readthedocs.io/en/stable/#)。
|
Python的openpyxl模块让我们可以在Python程序中读取和修改Excel电子表格,由于微软从Office 2007开始使用了新的文件格式,这使得Office Excel和LibreOffice Calc、OpenOffice Calc是完全兼容的,这就意味着openpyxl模块也能处理来自这些软件生成的电子表格。
|
||||||
|
|
||||||
|
```Python
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
from openpyxl import Workbook
|
||||||
|
|
||||||
|
wb = Workbook()
|
||||||
|
ws = wb.active
|
||||||
|
|
||||||
|
ws['A1'] = 42
|
||||||
|
ws.append([1, 2, 3])
|
||||||
|
ws['A2'] = datetime.datetime.now()
|
||||||
|
|
||||||
|
wb.save("sample.xlsx")
|
||||||
|
```
|
||||||
|
|
||||||
### 处理Word文档
|
### 处理Word文档
|
||||||
|
|
||||||
利用python-docx模块,Pytho 可以创建和修改Word文档,当然这里的Word文档不仅仅是指通过微软的Office软件创建的扩展名为docx的文档,LibreOffice Writer和OpenOffice Writer都是免费的字处理软件。
|
利用python-docx模块,Python可以创建和修改Word文档,当然这里的Word文档不仅仅是指通过微软的Office软件创建的扩展名为docx的文档,LibreOffice Writer和OpenOffice Writer都是免费的字处理软件。
|
||||||
|
|
||||||
|
```Python
|
||||||
|
from docx import Document
|
||||||
|
from docx.shared import Inches
|
||||||
|
|
||||||
### 处理PDF文档
|
document = Document()
|
||||||
|
|
||||||
PDF是Portable Document Format的缩写,使用.pdf作为文件扩展名。接下来我们就研究一下如何通过Python实现从PDF读取文本内容和从已有的文档生成新的PDF文件。
|
document.add_heading('Document Title', 0)
|
||||||
|
|
||||||
|
p = document.add_paragraph('A plain paragraph having some ')
|
||||||
|
p.add_run('bold').bold = True
|
||||||
|
p.add_run(' and some ')
|
||||||
|
p.add_run('italic.').italic = True
|
||||||
|
|
||||||
|
document.add_heading('Heading, level 1', level=1)
|
||||||
|
document.add_paragraph('Intense quote', style='Intense Quote')
|
||||||
|
|
||||||
|
document.add_paragraph(
|
||||||
|
'first item in unordered list', style='List Bullet'
|
||||||
|
)
|
||||||
|
document.add_paragraph(
|
||||||
|
'first item in ordered list', style='List Number'
|
||||||
|
)
|
||||||
|
|
||||||
|
document.add_picture('monty-truth.png', width=Inches(1.25))
|
||||||
|
|
||||||
|
records = (
|
||||||
|
(3, '101', 'Spam'),
|
||||||
|
(7, '422', 'Eggs'),
|
||||||
|
(4, '631', 'Spam, spam, eggs, and spam')
|
||||||
|
)
|
||||||
|
|
||||||
|
table = document.add_table(rows=1, cols=3)
|
||||||
|
hdr_cells = table.rows[0].cells
|
||||||
|
hdr_cells[0].text = 'Qty'
|
||||||
|
hdr_cells[1].text = 'Id'
|
||||||
|
hdr_cells[2].text = 'Desc'
|
||||||
|
for qty, id, desc in records:
|
||||||
|
row_cells = table.add_row().cells
|
||||||
|
row_cells[0].text = str(qty)
|
||||||
|
row_cells[1].text = id
|
||||||
|
row_cells[2].text = desc
|
||||||
|
|
||||||
|
document.add_page_break()
|
||||||
|
|
||||||
|
document.save('demo.docx')
|
||||||
|
```
|
||||||
|
|
|
@ -9,7 +9,7 @@ Date: 2018-03-02
|
||||||
"""
|
"""
|
||||||
import math
|
import math
|
||||||
|
|
||||||
for num in range(1, 10000):
|
for num in range(2, 10000):
|
||||||
result = 0
|
result = 0
|
||||||
for factor in range(1, int(math.sqrt(num)) + 1):
|
for factor in range(1, int(math.sqrt(num)) + 1):
|
||||||
if num % factor == 0:
|
if num % factor == 0:
|
||||||
|
|
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 73 KiB |
|
@ -10,24 +10,23 @@ Date: 2018-03-20
|
||||||
# 每个进程都有自己独立的内存空间 所以进程之间共享数据只能通过IPC的方式
|
# 每个进程都有自己独立的内存空间 所以进程之间共享数据只能通过IPC的方式
|
||||||
|
|
||||||
|
|
||||||
from multiprocessing import Process, Queue
|
from multiprocessing import Process, Queue, current_process
|
||||||
from time import sleep
|
from time import sleep
|
||||||
|
|
||||||
|
|
||||||
def sub_task(string, q):
|
def sub_task(content, counts):
|
||||||
number = q.get()
|
print(f'PID: {current_process().pid}')
|
||||||
while number:
|
counter = 0
|
||||||
print('%d: %s' % (number, string))
|
while counter < counts:
|
||||||
sleep(0.001)
|
counter += 1
|
||||||
number = q.get()
|
print(f'{counter}: {content}')
|
||||||
|
sleep(0.01)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
q = Queue(10)
|
number = random.randrange(5, 10)
|
||||||
for number in range(1, 11):
|
Process(target=sub_task, args=('Ping', number)).start()
|
||||||
q.put(number)
|
Process(target=sub_task, args=('Pong', number)).start()
|
||||||
Process(target=sub_task, args=('Ping', q)).start()
|
|
||||||
Process(target=sub_task, args=('Pong', q)).start()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 57 KiB |
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 57 KiB |
Before Width: | Height: | Size: 515 KiB After Width: | Height: | Size: 412 KiB |
Before Width: | Height: | Size: 262 B After Width: | Height: | Size: 239 B |
Before Width: | Height: | Size: 476 KiB After Width: | Height: | Size: 468 KiB |
Before Width: | Height: | Size: 98 KiB After Width: | Height: | Size: 98 KiB |
Before Width: | Height: | Size: 180 KiB After Width: | Height: | Size: 171 KiB |
|
@ -85,7 +85,7 @@
|
||||||
常用的工具类:
|
常用的工具类:
|
||||||
|
|
||||||
- `namedtuple`:命令元组,它是一个类工厂,接受类型的名称和属性列表来创建一个类。
|
- `namedtuple`:命令元组,它是一个类工厂,接受类型的名称和属性列表来创建一个类。
|
||||||
- `deque`:双端队列,是列表的替代实现。Python中的列表底层是基于数组来实现的,而deque底层是双向链表,因此当你需要在头尾添加和删除元素是,deque会表现出更好的性能,渐近时间复杂度为$O(1)$。
|
- `deque`:双端队列,是列表的替代实现。Python中的列表底层是基于数组来实现的,而deque底层是双向链表,因此当你需要在头尾添加和删除元素时,deque会表现出更好的性能,渐近时间复杂度为$O(1)$。
|
||||||
- `Counter`:`dict`的子类,键是元素,值是元素的计数,它的`most_common()`方法可以帮助我们获取出现频率最高的元素。`Counter`和`dict`的继承关系我认为是值得商榷的,按照CARP原则,`Counter`跟`dict`的关系应该设计为关联关系更为合理。
|
- `Counter`:`dict`的子类,键是元素,值是元素的计数,它的`most_common()`方法可以帮助我们获取出现频率最高的元素。`Counter`和`dict`的继承关系我认为是值得商榷的,按照CARP原则,`Counter`跟`dict`的关系应该设计为关联关系更为合理。
|
||||||
- `OrderedDict`:`dict`的子类,它记录了键值对插入的顺序,看起来既有字典的行为,也有链表的行为。
|
- `OrderedDict`:`dict`的子类,它记录了键值对插入的顺序,看起来既有字典的行为,也有链表的行为。
|
||||||
- `defaultdict`:类似于字典类型,但是可以通过默认的工厂函数来获得键对应的默认值,相比字典中的`setdefault()`方法,这种做法更加高效。
|
- `defaultdict`:类似于字典类型,但是可以通过默认的工厂函数来获得键对应的默认值,相比字典中的`setdefault()`方法,这种做法更加高效。
|
||||||
|
@ -147,7 +147,7 @@
|
||||||
items = items[:]
|
items = items[:]
|
||||||
for i in range(len(items) - 1):
|
for i in range(len(items) - 1):
|
||||||
swapped = False
|
swapped = False
|
||||||
for j in range(i, len(items) - 1 - i):
|
for j in range(len(items) - 1 - i):
|
||||||
if comp(items[j], items[j + 1]):
|
if comp(items[j], items[j + 1]):
|
||||||
items[j], items[j + 1] = items[j + 1], items[j]
|
items[j], items[j + 1] = items[j + 1], items[j]
|
||||||
swapped = True
|
swapped = True
|
||||||
|
@ -162,7 +162,7 @@
|
||||||
items = items[:]
|
items = items[:]
|
||||||
for i in range(len(items) - 1):
|
for i in range(len(items) - 1):
|
||||||
swapped = False
|
swapped = False
|
||||||
for j in range(i, len(items) - 1 - i):
|
for j in range(len(items) - 1 - i):
|
||||||
if comp(items[j], items[j + 1]):
|
if comp(items[j], items[j + 1]):
|
||||||
items[j], items[j + 1] = items[j + 1], items[j]
|
items[j], items[j + 1] = items[j + 1], items[j]
|
||||||
swapped = True
|
swapped = True
|
||||||
|
@ -792,11 +792,11 @@
|
||||||
Python使用了自动化内存管理,这种管理机制以**引用计数**为基础,同时也引入了**标记-清除**和**分代收集**两种机制为辅的策略。
|
Python使用了自动化内存管理,这种管理机制以**引用计数**为基础,同时也引入了**标记-清除**和**分代收集**两种机制为辅的策略。
|
||||||
|
|
||||||
```C
|
```C
|
||||||
typedef struct_object {
|
typedef struct _object {
|
||||||
/* 引用计数 */
|
/* 引用计数 */
|
||||||
int ob_refcnt;
|
int ob_refcnt;
|
||||||
/* 对象指针 */
|
/* 对象指针 */
|
||||||
struct_typeobject *ob_type;
|
struct _typeobject *ob_type;
|
||||||
} PyObject;
|
} PyObject;
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -1110,19 +1110,6 @@ Python中实现并发编程的三种方案:多线程、多进程和异步I/O
|
||||||
self.balance = new_balance
|
self.balance = new_balance
|
||||||
|
|
||||||
|
|
||||||
class AddMoneyThread(threading.Thread):
|
|
||||||
"""自定义线程类"""
|
|
||||||
|
|
||||||
def __init__(self, account, money):
|
|
||||||
self.account = account
|
|
||||||
self.money = money
|
|
||||||
# 自定义线程的初始化方法中必须调用父类的初始化方法
|
|
||||||
super().__init__()
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
# 线程启动之后要执行的操作
|
|
||||||
self.account.deposit(self.money)
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
"""主函数"""
|
"""主函数"""
|
||||||
account = Account()
|
account = Account()
|
||||||
|
@ -1130,14 +1117,6 @@ Python中实现并发编程的三种方案:多线程、多进程和异步I/O
|
||||||
pool = ThreadPoolExecutor(max_workers=10)
|
pool = ThreadPoolExecutor(max_workers=10)
|
||||||
futures = []
|
futures = []
|
||||||
for _ in range(100):
|
for _ in range(100):
|
||||||
# 创建线程的第1种方式
|
|
||||||
# threading.Thread(
|
|
||||||
# target=account.deposit, args=(1, )
|
|
||||||
# ).start()
|
|
||||||
# 创建线程的第2种方式
|
|
||||||
# AddMoneyThread(account, 1).start()
|
|
||||||
# 创建线程的第3种方式
|
|
||||||
# 调用线程池中的线程来执行特定的任务
|
|
||||||
future = pool.submit(account.deposit, 1)
|
future = pool.submit(account.deposit, 1)
|
||||||
futures.append(future)
|
futures.append(future)
|
||||||
# 关闭线程池
|
# 关闭线程池
|
||||||
|
@ -1166,12 +1145,12 @@ Python中实现并发编程的三种方案:多线程、多进程和异步I/O
|
||||||
import threading
|
import threading
|
||||||
|
|
||||||
|
|
||||||
class Account():
|
class Account:
|
||||||
"""银行账户"""
|
"""银行账户"""
|
||||||
|
|
||||||
def __init__(self, balance=0):
|
def __init__(self, balance=0):
|
||||||
self.balance = balance
|
self.balance = balance
|
||||||
lock = threading.Lock()
|
lock = threading.RLock()
|
||||||
self.condition = threading.Condition(lock)
|
self.condition = threading.Condition(lock)
|
||||||
|
|
||||||
def withdraw(self, money):
|
def withdraw(self, money):
|
||||||
|
@ -1212,9 +1191,10 @@ Python中实现并发编程的三种方案:多线程、多进程和异步I/O
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
account = Account()
|
account = Account()
|
||||||
with ThreadPoolExecutor(max_workers=10) as pool:
|
with ThreadPoolExecutor(max_workers=15) as pool:
|
||||||
for _ in range(5):
|
for _ in range(5):
|
||||||
pool.submit(add_money, account)
|
pool.submit(add_money, account)
|
||||||
|
for _ in range(10):
|
||||||
pool.submit(sub_money, account)
|
pool.submit(sub_money, account)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
## Web前端概述
|
## Web前端概述
|
||||||
|
|
||||||
> 说明:本文使用的部分插图来自*Jon Duckett*先生的*[HTML and CSS: Design and Build Websites](https://www.amazon.cn/dp/1118008189/ref=sr_1_5?__mk_zh_CN=%E4%BA%9A%E9%A9%AC%E9%80%8A%E7%BD%91%E7%AB%99&keywords=html+%26+css&qid=1554609325&s=gateway&sr=8-5)*一书,这是一本非常棒的前端入门书,有兴趣的读者可以在亚马逊或者其他网站上找到该书的购买链接。
|
> **说明**:本文使用的部分插图来自*Jon Duckett*先生的*[HTML and CSS: Design and Build Websites](https://www.amazon.cn/dp/1118008189/ref=sr_1_5?__mk_zh_CN=%E4%BA%9A%E9%A9%AC%E9%80%8A%E7%BD%91%E7%AB%99&keywords=html+%26+css&qid=1554609325&s=gateway&sr=8-5)*一书,这是一本非常棒的前端入门书,有兴趣的读者可以在亚马逊或者其他网站上找到该书的购买链接。
|
||||||
|
|
||||||
|
HTML 是用来描述网页的一种语言,全称是 Hyper-Text Markup Language,即超文本标记语言。我们浏览网页时看到的文字、按钮、图片、视频等元素,它们都是通过 HTML 书写并通过浏览器来呈现的。
|
||||||
|
|
||||||
### HTML简史
|
### HTML简史
|
||||||
|
|
||||||
|
@ -25,6 +27,10 @@
|
||||||
|
|
||||||
### 使用标签承载内容
|
### 使用标签承载内容
|
||||||
|
|
||||||
|
<img src="https://gitee.com/jackfrued/mypic/raw/master/20211107163448.png" style="zoom:35%">
|
||||||
|
|
||||||
|
<img src="https://gitee.com/jackfrued/mypic/raw/master/20211107163741.png" style="zoom:75%">
|
||||||
|
|
||||||
#### 结构
|
#### 结构
|
||||||
|
|
||||||
- html
|
- html
|
||||||
|
@ -93,11 +99,11 @@
|
||||||
|
|
||||||
- 重要属性 - action / method / enctype
|
- 重要属性 - action / method / enctype
|
||||||
- 表单控件(input)- type属性
|
- 表单控件(input)- type属性
|
||||||
- 文本框 - text / 密码框 - password / 数字框 - number
|
- 文本框 - `text` / 密码框 - `password` / 数字框 - `number`
|
||||||
- 邮箱 - email / 电话 - tel / 日期 - date / 滑条 - range / URL - url / 搜索 - search
|
- 邮箱 - `email` / 电话 - `tel` / 日期 - `date` / 滑条 - `range` / URL - `url` / 搜索 - `search`
|
||||||
- 单选按钮 - radio / 复选按钮 - checkbox
|
- 单选按钮 - `radio` / 复选按钮 - `checkbox`
|
||||||
- 文件上传 - file / 隐藏域 - hidden
|
- 文件上传 - `file` / 隐藏域 - `hidden`
|
||||||
- 提交按钮 - submit / 图像按钮 - image / 重置按钮 - reset
|
- 提交按钮 - `submit` / 图像按钮 - `image` / 重置按钮 - `reset`
|
||||||
- 下拉列表 - select / option
|
- 下拉列表 - select / option
|
||||||
- 文本域(多行文本)- textarea
|
- 文本域(多行文本)- textarea
|
||||||
- 组合表单元素 - fieldset / legend
|
- 组合表单元素 - fieldset / legend
|
||||||
|
@ -259,7 +265,7 @@
|
||||||
- 赋值运算符
|
- 赋值运算符
|
||||||
- 算术运算符
|
- 算术运算符
|
||||||
- 比较运算符
|
- 比较运算符
|
||||||
- 逻辑运算符
|
- 逻辑运算符:`&&`、`||`、`!`
|
||||||
- 分支结构
|
- 分支结构
|
||||||
- `if...else...`
|
- `if...else...`
|
||||||
- `switch...cas...default...`
|
- `switch...cas...default...`
|
||||||
|
|
Before Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 28 KiB |
|
@ -68,7 +68,7 @@
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<div>
|
<div>
|
||||||
<input @keydown.enter="addItem()" type="text" id="fname" v-model="fname">
|
<input @keydown.enter="addItem()" type="text" id="fname" v-model.trim="fname">
|
||||||
<button id="ok" @click="addItem()">确定</button>
|
<button id="ok" @click="addItem()">确定</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -82,8 +82,8 @@
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
addItem() {
|
addItem() {
|
||||||
if (this.fname.trim().length > 0) {
|
if (this.fname.length > 0) {
|
||||||
this.fruits.push(this.fname.trim())
|
this.fruits.push(this.fname)
|
||||||
}
|
}
|
||||||
this.fname = ''
|
this.fname = ''
|
||||||
},
|
},
|
||||||
|
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 4.6 KiB |
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.3 KiB |
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.4 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 4.6 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 71 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 71 KiB After Width: | Height: | Size: 69 KiB |
Before Width: | Height: | Size: 330 B After Width: | Height: | Size: 320 B |
Before Width: | Height: | Size: 505 B After Width: | Height: | Size: 292 B |
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 5.9 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 640 B After Width: | Height: | Size: 582 B |
Before Width: | Height: | Size: 474 B After Width: | Height: | Size: 334 B |
Before Width: | Height: | Size: 137 KiB After Width: | Height: | Size: 96 KiB |
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 87 KiB After Width: | Height: | Size: 83 KiB |
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 4.8 KiB |
Before Width: | Height: | Size: 136 KiB After Width: | Height: | Size: 128 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 8.6 KiB |
Before Width: | Height: | Size: 309 KiB After Width: | Height: | Size: 291 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 324 B After Width: | Height: | Size: 241 B |
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 90 KiB |
Before Width: | Height: | Size: 102 KiB After Width: | Height: | Size: 97 KiB |
Before Width: | Height: | Size: 108 KiB After Width: | Height: | Size: 103 KiB |
Before Width: | Height: | Size: 75 KiB After Width: | Height: | Size: 71 KiB |
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 459 B |
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 255 KiB After Width: | Height: | Size: 134 KiB |
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 395 B After Width: | Height: | Size: 260 B |
Before Width: | Height: | Size: 744 B After Width: | Height: | Size: 436 B |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 4.6 KiB |
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.3 KiB |
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.4 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 90 KiB |
Before Width: | Height: | Size: 102 KiB After Width: | Height: | Size: 97 KiB |
Before Width: | Height: | Size: 108 KiB After Width: | Height: | Size: 103 KiB |
Before Width: | Height: | Size: 75 KiB After Width: | Height: | Size: 71 KiB |
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 20 KiB |