十一、Python高阶技巧

Python高阶技巧

提示:本文根据b站黑马python课整理

链接指引 => 2022新版黑马程序员python教程



一、闭包

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

闭包注意事项:

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

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

缺点:

  • 由于内部函数持续引用外部函数的值,所以会导致这一部分内存空间不被释放,一直占用内存
"""
    简单闭包
"""
def outer(logo):
    def inner(msg):
        print(f"<{logo}>{msg}</{logo}>")

    return inner

fn1 = outer('小叮当')
fn1("111")

1.1 nonlocal关键字

nonlocal关键字的作用:
在闭包函数(内部函数中)想要修改外部函数的变量值
需要用nonlocal声明这个外部变量

"""
    关键字
"""

def outer(num1):
    def inner(num2):
        nonlocal num1

        num1 += num2
        print(num1)

    return inner

fn1 = outer(10)
fn1(10)
fn1(10)

1.2 ATM小案例

"""
    ATM小案例
"""
def account_create(initial_amount=0):
    def atm(num, deposit=True):
        nonlocal initial_amount
        if deposit:
            initial_amount += num
            print(f"存款:+{num},余额: {initial_amount}")
        else:
            initial_amount -= num
            print(f"取款:-{num},余额: {initial_amount}")

    return atm

fn = account_create(100)
fn(100)
fn(20, False)

二、装饰器

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

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

"""
    装饰器。。闭包写法
"""
def sleep():
    import random
    import time
    print('睡眠中。。。。')
    time.sleep(random.randint(1, 5))

def out(fun):
    def inner():
        print('我睡觉了...')
        fun()
        print('我起床了。。。')

    return  inner

fn = out(sleep)
fn()

2.2 装饰器的语法糖写法

"""
    装饰器。。语法糖写法
"""
def outer(fun):
    def inner():
        print('我睡觉了...')
        fun()
        print('我起床了。。。')

    return  inner

@outer
def sleep():
    import random
    import time
    print('睡眠中。。。。')
    time.sleep(random.randint(1, 5))

sleep()

三、设计模式

3.1 单例模式

单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。
在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场。

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

优点:

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

单例的实现模式:
单例模式

3.2 工厂模式

当需要大量创建一个类的实例的时候, 可以使用工厂模式。
即,从原生的使用类的构造去创建对象的形式
迁移到,基于工厂提供的方法去创建对象的形式

优点:

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

class Worker(Person):
    pass

class Student(Person):
    pass

class Teacher(Person):
    pass

class PersonFactory:
    def get_person(self, p_type):
        if p_type == 'w':
            return Worker()
        elif p_type == 's':
            return Student()
        else:
            return Teacher()


pf = PersonFactory()
worker = pf.get_person('w')
stu = pf.get_person('s')
te = pf.get_person('t')

四、多线程

4.1 进程、线程和并行执行

  1. 什么是进程
    程序在操作系统内运行,即成为一个运行进程
  2. 什么是线程
    进程内部可以有多个线程,程序的运行本质上就是由进程内部的线程在实际工作的。
  3. 什么是并行执行
    多个进程同时在运行,即不同的程序同时运行,称之为:多任务并行执行
    一个进程内的多个线程同时在运行,称之为:多线程并行执行

4.2 多线程编程

4.2.1 threading模块

threading
threading模块的使用:

  • thread_obj = threading.Thread(target=func) 创建线程对象
  • thread_obj.start() 启动线程执行

需要传参的话可以通过:

  • args参数通过元组(按参数顺序)的方式传参
  • 或使用kwargs参数用字典的形式传参
import time
import threading

def sing(msg):
    while True:
        print(f'我在嫦娥,啦啦啦。。。。。{msg}')
        time.sleep(1)


def dance(msg):
    while True:
        print(f"我在跳舞,挂怪瓜...{msg}")
        time.sleep(1)


if __name__ == '__main__':
    # sing()
    # dance()
    # 唱歌线程
    sing_thread = threading.Thread(target=sing, kwargs={'msg': '33333'})
    # 跳舞线程
    dance_thread = threading.Thread(target=dance, args=('11111', ))

    sing_thread.start()
    dance_thread.start()

五、网络编程

5.1 服务端开发

2个进程之间通过Socket进行相互通讯,就必须有服务端和客户端

Socket服务端:等待其它进程的连接、可接受发来的消息、可以回复消息
Socket客户端:主动连接服务端、可以发送消息、可以接收回复

Socket服务端编程

"""
    演示服务端Socker开发
"""
import socket
# 创建socker对象
socket_server = socket.socket()
# 绑定ip地址和端口
socket_server.bind(('127.0.0.1', 8888))
# 监听端口
socket_server.listen(1) # listen方法内接受一个证书参数,表示接收的链接数量
# 等待客户端链接
# result: tuple = socket_server.accept()
# conn = result[0]    # 客户端和服务端的链接对象
# address = result[1] # 客户端的地址信息
conn, address = socket_server.accept()
print(f'接受到了客户端信息,{address}')

while True:
    # 接受客户端信息
    # recv接受的参数是缓冲区大小,一般给1024即可
    data: str = conn.recv(1024).decode('UTF-8')
    print(f'客户端发来的消息是,{data}')
    # 发送回复消息
    msg = input('回复消息:')
    if msg == 'exit':
        break
    conn.send(msg.encode('UTF-8'))


# 关闭链接
conn.close()
socket_server.close()

5.2 客户端开发

"""
    演示服务端Socker开发
"""
import socket
# 创建socker对象
socket_server = socket.socket()
# 绑定ip地址和端口
socket_server.bind(('127.0.0.1', 8888))
# 监听端口
socket_server.listen(1) # listen方法内接受一个证书参数,表示接收的链接数量
# 等待客户端链接
# result: tuple = socket_server.accept()
# conn = result[0]    # 客户端和服务端的链接对象
# address = result[1] # 客户端的地址信息
conn, address = socket_server.accept()
print(f'接受到了客户端信息,{address}')

while True:
    # 接受客户端信息
    # recv接受的参数是缓冲区大小,一般给1024即可
    data: str = conn.recv(1024).decode('UTF-8')
    print(f'客户端发来的消息是,{data}')
    # 发送回复消息
    msg = input('回复消息:')
    if msg == 'exit':
        break
    conn.send(msg.encode('UTF-8'))
    

# 关闭链接
conn.close()
socket_server.close()

六、正则表达式

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

6.1 基础匹配

re模块的三个主要方法:

  • re.match,从头开始匹配,匹配第一个命中项
  • re.search,全局匹配,匹配第一个命中项
  • re.findall,全局匹配,匹配全部命中项
"""
    正则表达式匹配
"""
import re

s = 'python www python 1python'

res1 = re.match('python', s)
print(res1.group())
print(res1.span())
print(res1)


res2 = re.search('python1', s)
print(res2)

res3 = re.findall('python', s)
print(res3)

6.2 元字符匹配

单字符匹配:
单自负
数量匹配:
数量
边界匹配:
边界

分组匹配:
分组

规则
示例

七、递归

递归在编程中是一种非常重要的算法
递归: 即方法(函数)自己调用自己的一种特殊编程写法,函数调用自己,即称之为递归调用

递归

  1. 什么是递归
    在满足条件的情况下,函数自己调用自己的一种特殊编程技巧
  2. 递归需要注意什么?
  • 注意退出的条件,否则容易变成无限递归
  • 注意返回值的传递,确保从最内层,层层传递到最外层
  1. os模块的3个方法
  • os.listdir,列出指定目录下的内容
  • os.path.isdir,判断给定路径是否是文件夹,是返回True,否返回False
  • os.path.exists,判断给定路径是否存在,存在返回True,否则返回False

例如:
递归


总结

以上就是Python高阶技巧,之后会持续更新,欢迎大家点赞关注呀~~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值