PYTHON进阶
PYTHON进阶
闭包
- 在嵌套函数的前提下,内部函数使用了外部函数的变量,并且外部函数返回了内部函数,这个使用外部函数变量的内部函数称为闭包
- 优点:
- 无需定义全局变量即可实现通过函数,持续的访问、修改某个值
- 闭包使用的变量的作用域在函数内,难以被错误的调用修改
 
- 缺点:
- 由于内部函数持续引用外部函数的值,所以会导致这一部分内存空间不被释放,一直占用内存
 
# 例
def outer(logo):
    
    def inner(msg):
        print(f"<{logo}>{msg}<{logo}>")
       
    return inner
fn1 = outer("A")
fn1("B")
# 结果:<A>B<A>
修改外部函数变量的值
- 需要使用nonlocal关键字修饰外部函数的变量才可在内部函数中修改它
# 例
def outer(num1):
    def inner(num2):
        nonlocal num1
        num1 +=num2
        print(num1)
    return inner
fn1 = outer(10)
fn1(20)
# 结果:30
装饰器
- 装饰器其实也是一种闭包,其功能就是在不破坏目标函数原有的代码和功能的前提下,为目标函数增加新功能
def outer(func):
    def inner():
        print("function调用前")
        func()
        print("function调用后")
       
    return inner
- 装饰器的语法糖写法
def outer(func):
    def inner():
        print("我要睡觉了")
        func()
        print("我起床了")
       
    return inner
@outer
def sleep():
    import random
    import time
    print("睡眠中...")
    time.sleep(random.randint(1,5))
   
sleep()
设计模式
- 设计模式是一种编程套路,可以极大方便程序的开发
单例模式
- 保证一个类只有一个实例,并提供一个访问它的全局访问点
- 优点:
- 节省内存
- 节省创建对象的开销
 
# 例
class StrTools:
    pass
str_tool=StrTool()
# --------------------------------------------------------------------------
from test import str_tool
s1 = str_tool
s2 = str_tool
print(s1)
print(s2)
# s1 s2指向一个地址
工厂模式
- 从原生的使用类的构造取创建对象的形式迁移到,基于工厂提供的方法去创建对象的形式
- 优点:
- 大批量创建对象的时候有统一的入口,易于代码维护
- 当发生修改,仅修改工厂类的创建方法即可
 
class Person:
    pass
class Worker(Person):
    pass
class Student(Person):
    pass
class Teacher(Person):
    pass
class Factory:
    
    def get_person(self,p_type):
        if p_type = 'w':
            return Worker()
        elif p_type = 's':
            return Student()
        else:
            return Teacher()
 
factory = Factory()
worker = factory().get_person('w')
student = factory().get_person('s')
teacher = factory().get_person('t')
多线程
- 进程:就是一个程序,运行在系统上
- 线程:线程是归属于进程的,一个进程可以开启多个线程,执行不同的工作,是进程的实际工作最小单位
- 进程之间是内存隔离的,即不同的进程拥有各自的内存空间;线程之间是内存共享的
- 并行执行:指同一时间做不同的工作
- 进程之间就是并行执行的
- 线程也可以并行执行
 
threading模块
- PYTHON多线程可以通过threading模块来实现
import threading
thread_obj = threading.Thread(group= ,target= ,name= ,args= ,kwargs= )
# group:暂时不用,未来功能的预留参数
# target:执行的目标任务名
# name:线程名,一般不设置
# args:以元组的方式给执行任务传参
# kwargs:以字典方式给执行任务传参
# 启动线程,让线程开始工作
thread_obj.start()
import time
import threading
def sing():
    while True:
        print("SING~")
        time.sleep(1)
def dance():
    while True:
        print("DANCE~")
        time.sleep(1)
t1 = threading.Thread(target=sing)
t2 = threading.Thread(target=dance)
t1.start()
t2.start()
网络编程
Socket
- socket(简称:套接字)是进程之间通信的一个工具
- socket负责进程之间的网络数据传输
- 两个进程之间通过socket进行相互通讯,就必须有服务器和客户端
- socket服务端:等待其他进程的连接,可接收发来的信息,可以回复消息
- socket客户端:主动连接服务端,可以发送消息,可以接收消息
socket服务端
import socket
# 创建socket对象
socket_server=socket.socket()
# 绑定socket_server到指定IP和地址
socket_server.bind(('localhost',8888))
# 服务端开始监听端口
socket_server.listen(__backlog=5) # backlog为int整数,表示允许的连接数量,超出会等待,不填会自动设置一个合理值
# 接收客户端连接,获得连接对象
conn,address = socket_server.accept()
# accept是阻塞方法,没有连接会卡在当前行不向下执行代码
# accept返回的是一个二元元组(链接对象,客户端地址信息),可以使用上述形式,用两个变量接收二元元组的2个元素
print(f"接收到了客户端信息,客户端信息是:{address}")
# 客户端连接后,通过recv方法,接收客户端发送的信息
data = conn.recv(1024).decode("UTF-8")
# recv接收的参数是缓冲区大小,一般给1024即可
# recv方法的返回值是一个字节数组也就是byte对象,不是字符串,可以通过decode方法通过UTF-8编码转换为字符串对象
print(f"客户端消息:{data}")
# 通过conn(客户端当次连接对象),调用send方法可以回复信息
msg = input("请输入回复消息:").encode("UTF-8") # encode可以将字符串编码为字节数组对象
conn.send(msg)
# conn(客户端当次连接对象)和socket_server对象调用close方法,关闭连接
conn.close()
socket_server.close()
- 下载网络调试助手作为客户端测试
- [下载地址](Releases · nicedayzhu/netAssist (github.com))
- 打开exe
- 协议类型设置为TCP Client
 
socket客户端
import socket
# 创建socket对象
socket_client = socket.socket()
# 连接到服务端
socket_client.connect(('localhost',8888))
while True:
    # 发送消息
    msg = input("请输入要发送的消息:")
    socket_client.send(msg.encode("UTF-8"))
    if msg == 'exit':
        break
    # 接收返回消息
    recv_data = socket_client.recv(1024).decode("UTF-8")
    if recv_data == 'exit':
        break
    print(f"服务器回复的消息:{recv_data}")
# 关闭链接
socket_client.close()
正则表达式
- PYTHON正则表达式,使用re模块,并基于re模块中三个基础方法来做正则匹配
- 有match、search、findall三个基础方法
 
基础匹配
- 
re.match(匹配规则,被匹配字符串) - 从被匹配字符串开头进行匹配,匹配成功返回匹配对象(包含匹配的信息);匹配不成功返回空
 
- 
re.search(匹配规则,被匹配字符串) - 搜索整个字符串,找出匹配的,找到第一个就停止;找不到返回空
 
- 
re.findall(匹配规则,被匹配字符串) - 匹配整个字符串,找出全部匹配项;找不到返回空list:[]
 
元字符匹配
*正则表达式中的空格有意义
- 单字符匹配:
| 字符 | 功能 | 
|---|---|
| . | 匹配任意1个字符(除了\n),\.匹配点本身 | 
| [] | 匹配[]中列举的字符 | 
| \d | 匹配数字,即0-9 | 
| \D | 匹配非数字 | 
| \s | 匹配空白,即空格、tab键 | 
| \S | 匹配非空白 | 
| \w | 匹配单词字符,即a-z,A-Z,0-9,_ | 
| \W | 匹配非单词字符 | 
# 例
import re
s = "itheima1 @@python2 !!666 ##ticast3"
# 找出全部数字
a = re.findall(r'\d',s)
# 字符串的r标记,表示当前字符串是原始字符串,即内部的转义字符无效而是普通字符
# 找出特殊字符
a = re.findall(r'\W',s)
# 找出全部英文字母
a = re.findall(r'[a-zA-Z]',s)
print(a)
- 数量匹配:
| 字符 | 功能 | 
|---|---|
| * | 匹配前一个规则的字符出现0至无数次 | 
| + | 匹配前一个规则的字符出现1至无数次 | 
| ? | 匹配前一个规则的字符出现0次或1次 | 
| 匹配前一个规则的字符出现m次 | |
| 匹配前一个规则的字符出现最少m次 | |
| 匹配前一个规则的字符出现m到n次 | 
- 边界匹配:
| 字符 | 功能 | 
|---|---|
| ^ | 匹配字符串开头 | 
| $ | 匹配字符串结尾 | 
| \b | 匹配一个单词的边界 | 
| \B | 匹配非单词边界 | 
- 分组匹配:
| 字符 | 功能 | 
|---|---|
| | | 匹配左右任意一个表达式 | 
| () | 将括号中字符作为一个分组 | 
递归
- 方法(函数)自己调用自己的一种特殊编程写法
 
                    
                     
                    
                 
                    
                 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号