正则表达式
type
status
date
slug
summary
tags
category
icon
password
Property
 
字符串是编程时涉及到的最多的一种数据结构,对字符串进行操作的需求几乎无处不在。比如判断一个字符串是否是合法的Email地址,虽然可以编程提取@前后的子串,再分别判断是否是单词和域名,但这样做不但麻烦,而且代码难以复用。
正则表达式是一种用来匹配字符串的强有力的武器。它的设计思想是用一种描述性的语言来给字符串定义一个规则,凡是符合规则的字符串,我们就认为它“匹配”了,否则,该字符串就是不合法的。
所以判断一个字符串是否是合法的Email的方法是:
  1. 创建一个匹配Email的正则表达式;
  1. 用该正则表达式去匹配用户的输入来判断是否合法。
 
因为正则表达式也是用字符串表示的,所以要首先了解如何用字符来描述字符。
在正则表达式中,如果直接给出字符,就是精确匹配。
\d可以匹配一个数字,\w可以匹配一个字母或数字,所以:
  • '00\d'可以匹配'007',但无法匹配'00A'
  • '\d\d\d'可以匹配'010'
错误、调试和测试
type
status
date
slug
summary
tags
category
icon
password
Property

 

错误处理

程序运行的过程中,如果发生了错误,可以事先约定返回一个错误代码,这样可以知道是否有错以及出错的原因。在操作系统提供的调用中,返回错误码非常常见。比如打开文件的函数open(),成功时返回文件描述符(一个整数),出错时返回-1
 
用错误码来表示十分不便,因为函数返回的正常结果和错误码混在一起,调用者必须用大量的代码来判断是否出错:
一旦出错,还要一级一级上报,直到某个函数可以处理该错误(比如给用户输出一个错误信息),所以高级语言通常都内置了一套try...except...finally...的错误处理机制。
 
IO编程
type
status
date
slug
summary
tags
category
icon
password
Property
 
目录
目录

IO在计算机中指Input/Output,也就是输入和输出。由于程序和运行时数据是在内存中驻留,由CPU这个超快的计算核心来执行,涉及到数据交换的地方,通常是磁盘、网络等,就需要IO接口。
通常,程序完成IO操作会有InputOutput两个数据流。当然也有只用一个的情况,比如,从磁盘读取文件到内存,就只有Input操作,把数据写到磁盘文件里,就只是一个Output操作。
IO编程中,Stream(流)是一个很重要的概念,可以把流想象成一个水管,数据就是水管里的水,但是只能单向流动。Input Stream就是数据从外面(磁盘、网络)流进内存,Output Stream就是数据从内存流到外面去。对于浏览网页来说,浏览器和新浪服务器之间至少需要建立两根水管,才可以既能发数据,又能收数据。
 
由于CPU和内存的速度远远高于外设的速度,所以,在IO编程中,就存在速度严重不匹配的问题。比如要把100M的数据写入磁盘,CPU输出100M的数据只需要0.01秒,可是磁盘要接收这100M数据可能需要10秒,怎么办呢?有两种办法:
  • 第一种是CPU等着,也就是程序暂停执行后续代码,等100M的数据在10秒后写入磁盘,再接着往下执行,这种模式称为同步IO
  • 另一种方法是CPU不等待,只是告诉磁盘,“您老慢慢写,不着急,我接着干别的事去了”,于是,后续代码可以立刻接着执行,这种模式称为异步IO
进程和线程
type
status
date
slug
summary
tags
category
icon
password
Property
目录
目录

 
 
对于操作系统来说,一个任务就是一个进程(Process)进程内的这些“子任务”称为线程(Thread)
由于每个进程至少要干一件事,所以,一个进程至少有一个线程。多线程的执行方式和多进程是一样的,也是由操作系统在多个线程之间快速切换,让每个线程都短暂地交替运行,看起来就像同时执行一样。当然,真正地同时执行多线程需要多核CPU才可能实现。
 
怎么同时执行多个任务?
  • 多进程模式:启动多个进程,每个进程虽然只有一个线程,但多个进程可以一块执行多个任务。
  • 多线程模式:启动一个进程,在一个进程内启动多个线程,这样,多个线程也可以一块执行多个任务。
网络编程
type
status
date
slug
summary
tags
category
icon
password
Property

 
网络通信是两台计算机上的两个进程之间的通信。比如,浏览器进程和新浪服务器上的某个Web服务进程在通信,而QQ进程是和腾讯的某个服务器上的某个进程在通信。用Python进行网络编程,就是在Python程序本身这个进程内,连接别的服务器进程的通信端口进行通信

TCP编程

Socket是网络编程的一个抽象概念。通常用一个Socket表示“打开了一个网络链接”,而打开一个Socket需要知道目标计算机的IP地址和端口号,再指定协议类型即可。

客户端

大多数连接都是可靠的TCP连接。创建TCP连接时,主动发起连接的叫客户端,被动响应连接的叫服务器。
创建一个基于TCP连接的Socket,可以这样做:
模块
type
status
date
slug
summary
tags
category
icon
password
Property

使用模块有什么好处?
最大的好处是大大提高了代码的可维护性。其次,编写代码不必从零开始。当一个模块编写完毕,就可以被其他地方引用。在编写程序的时候,也经常引用其他模块,包括Python内置的模块和来自第三方的模块。
使用模块还可以避免函数名和变量名冲突。相同名字的函数和变量完全可以分别存在不同的模块中,因此,自己在编写模块时,不必考虑名字会与其他模块冲突。但是也要注意,尽量不要与内置函数名字冲突。

包(Package)

如果不同的人编写的模块名相同怎么办?为了避免模块名冲突,Python又引入了按目录来组织模块的方法,称为包(Package)
一个abc.py的文件就是一个名字叫abc的模块,一个xyz.py的文件就是一个名字叫xyz的模块。假设abcxyz这两个模块名字与其他模块冲突了,于是可以通过包来组织模块,避免冲突。方法是选择一个顶层包名,比如mycompany,按照如下目录存放:
notion image
引入了包以后,只要顶层的包名不与别人冲突,那所有模块都不会与别人冲突。现在,abc.py模块的名字就变成了mycompany.abc,类似的,xyz.py的模块名变成了mycompany.xyz
argparse
type
status
date
slug
summary
tags
category
icon
password
Property
目录
目录

 

argparse

notion image
 
 
以下代码是一个 Python 程序,它获取一个整数列表并计算总和或者最大值:
datetime
type
status
date
slug
summary
tags
category
icon
password
Property

 

获取当前日期和时间

获取当前日期和时间:
注意到datetime是模块,datetime模块还包含一个datetime类,通过from datetime import datetime导入的才是datetime这个类。
如果仅导入import datetime,则必须引用全名datetime.datetime
datetime.now()返回当前日期和时间,其类型是datetime
 
itertools
type
status
date
slug
summary
tags
category
icon
password
Property
目录
目录

 
Python的内建模块itertools提供了非常有用的用于操作迭代对象的函数。
首先,我们看看itertools提供的几个“无限”迭代器:
因为count()会创建一个无限的迭代器,所以上述代码会打印出自然数序列,根本停不下来,只能按Ctrl+C退出。
cycle()会把传入的一个序列无限重复下去:
同样停不下来。
collections
type
status
date
slug
summary
tags
category
icon
password
Property

namedtuple

tuple可以表示不变集合,例如,一个点的二维坐标就可以表示成:p = (1, 2)
但是,看到(1, 2),很难看出这个tuple是用来表示一个坐标的。定义一个class又小题大做了,这时namedtuple就派上了用场:
namedtuple是一个函数,它用来创建一个自定义的tuple对象,并且规定了tuple元素的个数,并可以用属性而不是索引来引用tuple的某个元素
这样一来,用namedtuple可以很方便地定义一种数据类型,它具备tuple的不变性,又可以根据属性来引用,使用十分方便。
可以验证创建的Point对象是tuple的一种子类:
contextlib
type
status
date
slug
summary
tags
category
icon
password
Property
目录
目录

 
Python中,读写文件这样的资源要特别注意,必须在使用完毕后正确关闭它们。正确关闭文件资源的一个方法是使用try...finally
try...finally非常繁琐。Pythonwith语句可以非常方便地使用资源,而不必担心资源没有关闭,上面的代码可以简化为:
并不是只有open()函数返回的fp对象才能使用with语句。实际上,任何对象,只要正确实现了上下文管理,就可以用于with语句。
 
实现上下文管理是通过__enter____exit__这两个方法实现的。例如,下面的class实现了这两个方法:
base64、struct、chardet
type
status
date
slug
summary
tags
category
icon
password
Property
目录
目录

base64

Base64是一种用64个字符来表示任意二进制数据的方法。
用记事本打开exejpgpdf这些文件时,我们都会看到一大堆乱码,因为二进制文件包含很多无法显示和打印的字符,所以,如果要让记事本这样的文本处理软件能处理二进制数据,就需要一个二进制到字符串的转换方法。Base64是一种最常见的二进制编码方法。
Base64的原理很简单,首先,准备一个包含64个字符的数组:['A', 'B', 'C', ... 'a', 'b', 'c', ... '0', '1', ... '+', '/']
然后,对二进制数据进行处理,每3个字节一组,一共是3x8=24bit,划为4组,每组正好6个bit:
notion image
这样得到4个数字作为索引,然后查表,获得相应的4个字符,就是编码后的字符串。
所以,Base64编码会把3字节的二进制数据编码为4字节的文本数据,长度增加33%,好处是编码后的文本数据可以在邮件正文、网页等直接显示。