四、Python高级

文章介绍了Python中的闭包概念,通过示例展示了如何使用闭包来管理外部变量。接着讨论了装饰器,它是创建闭包函数以增强原函数功能的一种方式。此外,文章还讲解了单例模式,确保类只有一个实例。工厂模式则提供了统一的对象创建接口。最后,文章涉及了多线程编程,包括创建和管理线程以及服务端和客户端的简单实现。
摘要由CSDN通过智能技术生成

1、闭包:

1、定义双层嵌套函数,内层函数可以访问外层函数的变量
2、将内层函数作为外层函数的返回值,此内层函数就是闭包函数
3、要修改外层函数的值:使用nonlocal

不使用闭包:
# 将account_amount暴露在外不安全
account_amount = 0
def atm(num, deposit = True):
    global account_amount
    if deposit:
        account_amount += num
        print(f"存款:+{num},余额为“{account_amount}")
    else:
        account_amount -= num
        print(f"取款:-{num},余额为“{account_amount}")

atm(100)
atm(200)
atm(200,False)
使用闭包:

```# 为了解决内部函数需要访问外部变量的但又不想暴露外部变量的问题可以使用闭包:
def account(account_amount = 0):
    def atm(num, deposit=True):
        # 修改外部变量函数的值:nonlocal
        nonlocal account_amount
        if deposit:
            account_amount += num
            print(f"存款:+{num},余额为“{account_amount}")
        else:
            account_amount -= num
            print(f"取款:-{num},余额为“{account_amount}")

    return atm

ac1 = account()
ac1(100)
ac1(200)
ac1(100,False)

2、装饰器:

装饰器:就是创建一个闭包函数,在闭包函数内调用目标函数。
可以达到不改动目标函数的同时,增加额外功能。
前提是有一个闭包函数。

普通写法:

def outer(func):
    def inner():
        print("我睡觉了")
        func()
        print("我起床了")
    return inner

def sleep():
    import random
    import time
    print("睡眠中.....")
    time.sleep(random.randint(1,4))

# 调用outer()将sleep函数作为参数传入outer方法中,并赋值给函数调用者fn
# fn = inner  outer函数范沪指
# 调用fn() = 调用inner()
# inner函数执行,打印“我睡觉了” --> 调用func()=sleep() 输出“睡眠中” --> 输出"我起床了”
fn = outer(sleep)
fn()

语法糖写法:

def outer(func):
    def inner():
        print("我睡觉了")
        func()
        print("我起床了")
    return inner

def sleep():
    import random
    import time
    print("睡眠中.....")
    time.sleep(random.randint(1,4))

@outer
def sleep():
    import random
    import time
    print("睡眠中.....")
    time.sleep(random.randint(1,4))

sleep()

3、单例模式:

单例模式:就是对一个类,只获取其惟一的类实例对象,并持续复用他。
可以节省内存

在当前类中创建的实例对象是不同的

class Toll:
    pass

toll1 = Toll()
toll2 = Toll()
# 可以看见在同一个文件中获取的类对象是不一样的。
print(toll1) # 0x000001F5F02BFD90
print(toll2) # 0x000001F5F02BFD10

在别的文件中导入的话创建的类对象是一样的

from Singleto import Toll

too1 = Toll
too2 = Toll

print(too1) # 0x000001F5F02BFD90
print(too2) # 0x000001F5F02BFD10

4、工厂模式:

将对象的创建由原生态的创建转换到由特定工厂方法创建
1、利于大批量创建对象时有统一的入口,易于维护代码。
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')
teacher = pf.get_person('t')

5、多线程:threadingmok

在这里插入图片描述

import time
import threading

def sing(msg):
    while True:
        print(msg)
        time.sleep(1)

def dance(msg):
    while True:
        print(msg)
        time.sleep(1)

if __name__ == '__main__':
    # 1、创建一个唱歌的线程
    sing_thread = threading.Thread(target=sing, args=('我在唱歌,哈哈哈',))
    # 2、创建一个跳舞线程
    dance_thread = threading.Thread(target=dance,kwargs={'msg':'我在跳舞,啦啦啦'})

    # 3、启动线程:
    sing_thread.start()
    dance_thread.start()

6、服务端开发:

# 1、导入socket模块
import socket
# 2、创建Socket对象
socket_server = socket.socket()
# 3、绑定IP地址和端口 bind()接收一个二元元组参数
socket_server.bind(('localhost',8888))
# 4、监听端口 listen(int) 接收一个整数,表示可以同时建立几个连接
socket_server.listen(1)
# 5、等待客户端连接 accept()返回一个二元元组(连接对象,客户端地址信息)
# 简写:
conn, address = socket_server.accept()

# accept()方法是一个阻塞方法,如果没有 连接,代码不再往下执行
print(f'接收到了客户端连接,客户端信息为:{address}')

while True:
    # 接收客户端信息,要使用客户端和服务端本次连接的对象(因为可能服务端一次连接多个客户端对象),而非socket_server对象
    # recv(缓冲区大小):一般1024即可
    # recv方法返回值:字节数组也就是bytes对象,而非字符串,因此需要解码:decode方法解码
    data:str = conn.recv(1024).decode('UTF-8')
    print(f'客户端发来的消息是:{data}')
    # 发送回复信息
    msg = input('请输入要和客户端回复的消息:')
    if msg == 'exit':
        break
    # encode()将字符串解码为字节数组
    conn.send(msg.encode('UTF-8'))

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

7、客户端开发:

# 1、导入socket模块
import socket
# 2、创建socket对象
socket_client = socket.socket()
# 3、连接到服务器
socket_client.connect(('localhost',8888))

while True:
    # 发送消息
    msg = input('请输入要给服务端发送的消息:')
    if msg == 'exit':
        break
    socket_client.send(msg.encode('UTF-8'))
    # 接收返回的消息
    recv_data = socket_client.recv(1024)
    print(f'服务端回复的消息是:{recv_data.decode("UTF-8")}')

# 关闭连接
socket_client.close()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值