python核心 - 网络编程
自从互联网诞生以来,现在基本上所有的程序都是网络程序。 网络编程对所有开发语言都是一样的,Python也不例外。 用Python进行网络编程,就是在Python程序本身这个进程内,连接别的服务器进程的通信端口进行通信。 本章我们将详细介绍Python网络编程的概念和最主要的两种网络类型的编程。
自从互联网诞生以来,现在基本上所有的程序都是网络程序。 网络编程对所有开发语言都是一样的,Python也不例外。 用Python进行网络编程,就是在Python程序本身这个进程内,连接别的服务器进程的通信端口进行通信。 本章我们将详细介绍Python网络编程的概念和最主要的两种网络类型的编程。
操作数据库是最常见的任务,这里用MySQL来做演示,也是我们用的最多的一个开源数据库,其他都类似的。
对于安装MySQL就不做介绍了,安装完后,还需要安装去驱动。因为需要支持Python的MySQL驱动来连接到MySQL服务器。 MySQL的驱动有多种实现,比如纯python实现的pymysql和mysql-connector,或者mysql-python也就是MySQLdb。
这里我通过mysql-connector来介绍使用方法:
1 | pip install mysql-connector |
单元测试在所有编程语言中都不陌生,对于一个健壮的软件来讲单元测试是很有必要的, 并且”测试驱动开发”(TDD:Test-Driven Development)越来越受欢迎也说明了它的重要性。
单元测试一个最大的好处,就是确保一个程序模块的行为符合我们设计的测试用例。 在将来修改的时候,可以极大程度地保证该模块行为仍然是正确的。
由于CPU的速度远远快于磁盘、网络等IO,我们可选择使用多进程或多线程来并发执行代码。 然而系统不能无限制增加线程,而且切换线程开销也大,一旦线程数量过多,CPU花的时间主要在切换线程上,导致性能下降。
另外一种解决方案是异步IO,当代码需要执行一个耗时的IO操作时,它只发出IO指令,并不等待IO结果,然后就去执行其他代码了。 一段时间后,当IO返回结果时,再通知CPU进行处理。
异步IO模型需要一个消息循环,在消息循环中,主线程不断地重复”读取消息-处理消息”这一过程:
1 | loop = get_event_loop() |
息模型是如何解决同步IO必须等待IO操作这一问题的呢?当遇到IO操作时,代码只负责发出IO请求,不等待IO结果, 然后直接结束本轮消息处理,进入下一轮消息处理过程。当IO操作完成后,将收到一条”IO完成”的消息, 处理该消息时就可以直接获取IO操作结果。
IO在计算机中指Input/Output,也就是输入和输出。由于程序和运行时数据是在内存中驻留, 由CPU这个超快的计算核心来执行,涉及到数据交换的地方,通常是磁盘、网络等,就需要IO接口。
通常,程序完成IO操作会有Input和Output两个数据流。当然也有只用一个的情况, 比如,从磁盘读取文件到内存,就只有Input操作,反过来,把数据写到磁盘文件里,就只是一个Output操作。
Stream(流)是一个很重要的概念,可以把流想象成一个水管,数据就是水管里的水,但是只能单向流动。 Input Stream就是数据从外面(磁盘、网络)流进内存,Output Stream就是数据从内存流到外面去。
现在是多核和并发时代,所以不管什么语言都要支持这个特性。并发是看上去同时执行,并行是在多核上同时执行。
我们先解释下线程和进程。简单来说,一个任务就是一个进程(Process)。 在一个进程内部,要同时干多件事,就需要同时运行多个进程内的”子任务”,这些子任务就叫线程(Thread)
线程是最小的执行单元,而进程由至少一个线程组成。如何调度进程和线程, 完全由操作系统决定,程序自己不能决定什么时候执行,执行多长时间。
多进程和多线程的程序涉及到同步、数据共享的问题,编写起来更复杂。
日期和时间是我们编程经常需要处理的事情,相比较其他语言,python中的日期和时间处理非常简洁。 datetime是python处理日期和时间的标准库。
python中有一个datetime模块,里面有个datetime类,这里大家先要弄清楚,很容易搞混。
所以我们获取当前日期和时间的代码如下:
1 | from datetime import datetime |
如果仅导入·import datetime·,则必须引用全名datetime.datetime
。
datetime.now()
返回当前日期和时间,其类型是datetime
字符串是编程时涉及到的最多的一种数据结构,对字符串进行操作的需求几乎无处不在。
正则表达式是一种用来匹配字符串的强有力的武器。它的设计思想是用一种描述性的语言来给字符串定义一个规则, 凡是符合规则的字符串,我们就认为它”匹配”了,否则,该字符串就是不合法的。
我们判断一个字符串是否是一个合法的电话号码分两步,首先创建一个符合电话号码规则的正则表达式, 然后用这个正则表达式来匹配这个字符串是否合法。
动态语言和静态语言最大的不同,就是函数和类的定义,不是编译时定义的,而是运行时动态创建的。我们在hello.py模块里定义一个Hello的 当Python解释器载入hello模块时,就会依次执行该模块的所有语句,执行结果就是动态创建出一个Hello的class对象。
我们说class的定义是运行时动态创建的,而创建class的方法就是使用type()函数。
type()函数既可以返回一个对象的类型,又可以创建出新的类型。
面向对象编程——Object Oriented Programming,简称OOP,是一种程序设计思想。 OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。
面向过程的程序设计把计算机程序视为一系列的命令集合,即一组函数的顺序执行。 为了简化程序设计,面向过程把函数继续切分为子函数,即把大块函数通过切割成小块函数来降低系统的复杂度。
而面向对象的程序设计把计算机程序视为一组对象的集合,而每个对象都可以接收其他对象发过来的消息, 并处理这些消息,计算机程序的执行就是一系列消息在各个对象之间传递。
在Python中,所有数据类型都可以视为对象,当然也可以自定义对象。 自定义的对象数据类型就是面向对象中的类(Class)的概念。