第十一章 Python语言-高阶技巧(终章)

目录

一.闭包

二.装饰器

三.设计模式

1.单例模式

2.工厂模式

四.多线程

1.进程、线程和并行执行的概念

2.多线程编程

五.网络编程

1.服务器端开发

2.客户端开发

六.正则表达式

1.正则的基础匹配方法

2.元字符匹配

七.递归


此章节是Python语言的最后一个语法知识点和最后一个运用知识点了,经过这几天的高强度学习Python。我也是从零到现在对于Python的语法有了深刻的了解和认识了。

也从这一个章节我成功学完如今四大热门编程语言:C语言、C++、Java、Python。

此章节主要讲解的内容是:“闭包”、“装饰器”、“设计模式”、“多线程”、“网络编程”、“正则表达式”、“递归”。

一.闭包

通过全局变量account amount来记录余额

尽管功能实现是ok的,但是仍有问题:

  • 代码在命名空间上(变量定义)不够干净、整洁
  • 全局变量有被修改的风险

由上图来引出“闭包”的概念。

闭包的概念:在函数嵌套的前提下,内部函数使用了外部函数的变量,并且外部函数返回了内部函数,我们把这个使用外部函数变量的内部函数称为闭包。

简单闭包的代码示例如下:

若需要在内部函数去修改外部函数的变量,需要使用nonlocal关键字修饰外部函数的变量才可在内部函数中修改它。

不使用nonlocal关键字代码演示如下:

使用nonlocal关键字代码演示如下:

闭包注意事项

优点,使用闭包可以让我们得到:

  • 无需定义全局变量即可实现通过函数,持续的访问、修改某个值
  • 闭包使用的变量的所用于在函数内,难以被错误的调用修改

缺点:

  • 由于内部函数持续引用外部函数的值,所以会导致这一部分内存空间不被释放,一直占用内存

总结:

1.什么是闭包

定义双层嵌套函数,内层函数可以访问外层函数的变量

将内存函数作为外层函数的返回,此内层函数就是闭包函数

2.闭包的好处和缺点

  • 优点:不定义全局变量,也可以让函数持续访问和修改一个外部变量
  • 优点:闭包函数引用的外部变量,是外层函数的内部变量。作用域封闭难以被误操作修改
  • 缺点:额外的内存占用

3.nonlocal关键字的作用

在闭包函数(内部函数中)想要修改外部函数的变量值

需要用nonlocal声明这个外部变量

二.装饰器

装饰器

装饰器其实也是一种闭包,其功能就是在不破坏目标函数原有的代码和功能的前提下,为目标函数增加新功能

希望给sleep函数,增加一个功能

  • 在调用sleep前输出:我要睡觉了
  • 在调用sleep后输出:我起床了

装饰器的一般写法(闭包写法)

一般写法的装饰器代码演示如下:

装饰器的语法糖写法代码演示案例如下:

总结:

1.什么是装饰器

装饰器就是使用创建一个闭包函数,在闭包函数内调用目标函数。

可以达到不改动目标函数的同时,增加额外的功能。

2.装饰器的写法

三.设计模式

设计模式是一种编程套路,可以极大的方便程序的开发。

最常见、最经典的设计模式,就是我们所学习的面向对象了。

除了面向对象外,在编程中也有很多既定的套路可以方便开发,我们称之为设计模式

  • 单例、工厂模式
  • 建造者、责任链、状态、备忘录、解释器、访问者、观察者、中介、模板、代理模式
  • 等等模式

设计模式非常多,我们主要挑选了2个经常用到的进行讲解。

1.单例模式

单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。

在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场。

  • 定义:保证一个类只有一个实例,并提供一个访问它的全局访问点
  • 运用场景:当一个类只能有一个实例,而客户可以从一个众所周知的访问点访问它时。

单例模式的代码演示如下:

总结:

1.什么是设计模式

设计模式就是一种编程套路。

使用特定的套路得到特定的效果

2.什么是单例设计模式

单例模式就是对一个类,只获取其唯一的类实例对象,持续复用它。

  • 节省内存
  • 节省创建对象的开销

2.工厂模式

工厂设计模式代码演示如下:

总结:

1.什么是工厂模式

将对象的创建由使用原生类本身创建

转换到由特定的工厂方法来创建

2.好处

  • 大批量创建对象的时候有统一的入口,易于代码维护
  • 当发生修改,仅修改工厂类的创建方法即可
  • 符合现实世界的模式,即由工厂来制作产品(对象)

四.多线程

1.进程、线程和并行执行的概念

现代操作系统比如Mac OSX,UNIX,Linux,Windows等,都是支持“多任务”的操作系统。

进程:就是一个程序,运行在系统之上,那么便称之这个程序为一个运行进程,并分配进程ID方便系统管理。

线程:线程是归属于进程的,一个进程可以开启多个线程,执行不同的工作,是进程的实际工作最小单位。

进程就好比一家公司,是操作系统对程序进行运行管理的单位

线程就好比公司的员工,进程可以有多个线程(员工),是进程实际的工作者

操作系统中可以运行多个进程,即多任务运行

一个进程内可以运行多个线程,即多线程运行

注意点:

进程之间是内存隔离的,即不同的进程拥有各自的内存空间。这就类似于不同的公司拥有不同的办公场所。

线程之间是内存共享的,线程是属于进程的,一个进程内的多个线程之间是共享这个进程所拥有的内存空间的,。

这就好比,公司员工之间是共享公司的办公场所。

并行执行

并行执行的意思指的是同一时间做不同的工作。

进程之间就是并行执行的,操作系统可以同时运行好多程序,这些程序都是在并行执行。

除了进程外,线程其实也是可以并行执行的。

也就是比如一个Python程序,其实是完全可以做到:

  • 一个线程在输出:你好
  • 一个线程在输出:Hello

像这样一个程序在同一时间做两件乃至多件不同的事情,我们就称之为:多线程并行执行

总结:

1.什么是进程

程序在操作系统内运行,即成为一个运行进程

2.什么是线程

进程内部可以有多个线程,程序的运行本质上就是由进程内部的线程在实际工作的。

3.什么是并行执行

  • 多个进程同时在运行,即不同的程序同时运行,称之为:多任务并行执行
  • 一个进程内的多个线程同时在运行,称之为:多线程并行执行

2.多线程编程

threading模块

绝大多数编程语言,都允许多线程编程,Pyhton也不例外。

Python的多线程可以通过threading模块来实现。

多线程编程代码演示案例如下:

控制多线程的任务演示代码如下:

总结:

1.threading模块的使用

thread obj=threading.Thread(target=func)创建线程对象

thread obj.start()启动线程执行

2.如何传参

五.网络编程

此小节主要分为:服务器端开发和客户端开发

socket的介绍:socket(简称 套接字)是进程之间通信一个工具,好比现实生活中的插座,所有的家用电器要想工作都是基于插座进行,进程之间想要进行网络通信需要socket

Socket负责进程之间的网络数据,好比数据的搬运工。

1.服务器端开发

Socket服务端编程

主要分为如下几个步骤:

(1).创建socket对象

(2)绑定socket_server到指定IP和地址

(3)服务端开发监听端口

(4)接收客户端连接,获得连接对象

(5)客户端连接后,通过recv方法,接收客户端发送的消息

(6)通过conn(客户端当次连接对象),调用send方法可以回复消息

(7)coon(客户端当次连接对象)和socket_server对象调用close方法,关闭连接

网络编程代码示例如下

总结:

2.客户端开发

Socket客户端编程开发步骤如下:

(1)创建socket对象

(2)连接到服务端

(3)发送消息

(4)接收返回消息

(5)关闭链接

网络编程—客户端开发演示代码如下:

六.正则表达式

此小节分为:基础匹配和元字符匹配

正则表达式的概念:正则表达式,又称规则表达式(RegularExpression),是使用单个字符串来描述、匹配某个句法规则的字符串,常被用来检索、替换那些符合某个模式(规则)的文本。

简单来说,正则表达式就是使用:字符串定义规则,并通过规则去验证字符串是否匹配。

比如,验证一个字符串是否是符合条件的电子邮箱地址,只需要配置好正则规则,即可匹配任意邮箱。

比如通过正则规则:(^[w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$)即可匹配一个字符串是否是标准邮箱格式

但如果不使用正则,使用if else来对字符串做判断就非常困难了。

我们如果无法判断自己写的正则表达式是否正确可以使用如下网站去测试:

在线正则表达式测试

1.正则的基础匹配方法

Python正则表达式,使用re模块,并基于re模块中三个基础方法来做正则匹配。

分别是: match、search、findall 三个基础方法

  • re.match(匹配规则,被匹配字符串)

从被匹配字符串开头进行匹配,匹配成功返回匹配对象(包含匹配的信息),匹配不成功返回空。

match从头匹配代码演示如下:

匹配失败如下:

匹配成功如下:

  • search(匹配规则,被匹配字符串)

搜索整个字符串,找出匹配的。从前向后,找到第一个后,就停止,不会继续向后。

整个字符串都找不到,返回None

search正则表达式代码演示如下:

成功匹配如下:

失败匹配如下:

  • findall(匹配规则,被匹配字符串)

匹配整个字符串,找出全部匹配项

找不到返回空list:[]

findall正则表达式代码演示如下:

找到的返回值如下:

未找到的如下:

总结:

1.什么是正则表达式

是一种字符串验证的规则,通过特殊的字符串组合来确立规则

用规则去匹配字符串是否满足

(^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$)可以表示为一个标准邮箱的格式

2.re模块的三个主要方法

  • re.match,从头开始匹配,匹配第一个命中项
  • re.search,全局匹配,匹配第一个命中项
  • re.findall,全局匹配,匹配全部命中项

2.元字符匹配

在刚刚我们只是进行了基础的字符串匹配,正则最强大的功能在于元字符匹配规则。

单字符匹配:

示例:

字符串s=“itheima1 @@python2 !!666 ##itcast3

  • 找出全部数字:

re.findall(r'\d's)

字符串的r标记,表示当前字符串是原始字符串,即内部的转义字符无效而是普通字符

  • 找出特殊字符:

re.findall(r'\W',s)

  • 找出全部英文字母:

re.findall(r'[a-zA-Z] ',s)

[]内可以写:[a-zA-Z0-9]这三种范围组合或指定单个字符如[aceDFG135]

代码演示如下:

数量匹配:

边界匹配

分组匹配:

代码演示如下:

总结:

  1. 字符串的r标记表示,字符串内转移字符无效,作为普通字符使用
  2. 正则表达式的元字符规则

测试正则表达式是否正确的网站:在线正则表达式测试

七.递归

递归在编程中是一种非常重要的算法

递归:即方法(函数)自己调用自己的一种特殊编程写法

如:

函数调用自己,即称之为递归调用。

代码演示如下:

总结:

1.什么是递归

在满足条件的情况下,函数自己调用自己的一种特殊编程技巧

2.递归需要注意什么?

  • 注意退出的条件,否则容易变成无限递归
  • 注意返回值的传递,确保从最内层,层层传递到最外层

3.os模块的3个方法

  • os.listdir,列出指定目录下的内容
  • os.path.isdir,判断给定路径是否是文件夹,是返回True,否返回False
  • os.path.exists,判断给定路径是否存在,存在返回True,否则返回False