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()

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 匹配非单词边界
  • 分组匹配:
字符 功能
| 匹配左右任意一个表达式
() 将括号中字符作为一个分组

递归

  • 方法(函数)自己调用自己的一种特殊编程写法
posted @ 2023-03-10 12:22  Learn1ng  阅读(100)  评论(0)    收藏  举报