python高级基础
闭包
简单解释一下闭包就是可以在内部访问外部函数的变量,因为如果声明全局变量,那在后面就有可能会修改
在闭包中的内部函数如果要修改外部变量就要借助nonlocal关键字
def outer(num1):
def inner(num2):
nonlocal num1
num1+=num2
print(num1,num2)
return inner
fn=outer(10)
fn(10) # 20
fn(10) # 30
修饰器
闭包修饰器语法
def outer(fn):
def inner():
print('我睡觉了')
fn()
print('醒了')
return inner
def sleep():
import random
import time
print('睡眠中。。。')
time.sleep(random.randint(1,5))
fn1=outer(sleep)
fn1()
注意看加粗的两个地方是语法糖 实际原理还是用的是闭包
单例模式跟工厂模式
工厂模式
优点:创建出来的每个对象都是独立的地址
缺点:部分属性不一致,但是都是独立的内存,消耗内存性能
class Person:
pass
class Student(Person):
pass
class Worker(Person):
pass
class Teacher(Person):
pass
class PersonFac:
def get_person(self,type):
if(type=='s'):
return Student()
elif(type=='w'):
return Worker()
else:
return Teacher()
pf=PersonFac()
worker=pf.get_person('w')
stu=pf.get_person('s')
teacher=pf.get_person('t')
print(worker,stu,teacher)
单例模式
实例化类,然后在这个单例类上面进行添加删除
# class Stu:
# pass
#
# t1=Stu()
# t2=Stu()
# print(id(t1)) # 1755386051920
# print(id(t2)) # 1755386051984
# 单例写法 工作中常把创建类单独提出文件 然后引入
class Stu:
pass
t1=Stu()
s1=t1
s2=t1
print(id(s1)) # 1790597823824
print(id(s2)) # 1790597823824
多线程多进程
以下代码是单线程执行,最终输出结果是一直执行sing方法因为是无限循环的
import time
def sing():
while True:
print('我在唱歌。。。')
time.sleep(1)
def dance():
while True:
print('我在跳舞。。。')
time.sleep(1)
if __name__=='__main__':
sing()
dance()
def sing(msg):
while True:
print(msg)
time.sleep(1)
def dance(msg):
while True:
print(msg)
time.sleep(1)
if __name__=='__main__':
singThread=threading.Thread(target=sing,args=('我要唱歌',)) # 使用Thread方法开启线程 参数要一一对应不然就会跑到第一个参数所以这边使用具名参数
danceThread=threading.Thread(target=dance,kwargs={'msg':'我在跳舞'})
singThread.start() # 线程启动
danceThread.start()
这里面2个注意点
- 以元祖形式传参,一个参数别忘了逗号
- 以字典形式传参,参数要与方法参数一一对应不然会报错,参数名也不能变
创建websocket
服务端
import socket
# 创建socket对象
socket_server=socket.socket()
# 绑定ip地址和端口
socket_server.bind(("localhost",8888))# 千万注意这里的传参是元组
# 监听端口
socket_server.listen(1)
# listen接收一个整数传参数,表示接收的链接数量
# 等待客户端链接
# result:tuple=socket_server.accept()
# conn=result[0] # 客户端和服务端的链接对象
# address=result[1] # 客户端的地址信息
# 简写
conn,address =socket_server.accept() # 返回的是二元元祖(连接对象,客户端地址信息)
# 此方法是阻塞的 accept 如果没有链接下面的代码不执行
print(f'接收到了{address}')
# 无线循环发消息 ,最终根据最后逻辑进行跳出自行解决
while True:
data:str=conn.recv(1024).decode('GBK')
print(f'客户顿发来的信息是{data}')
msg=input('发送信息').encode("GBK")
conn.send(msg)
#关闭链接
conn.close()
socket_server.close()
如果报这种错说明你的数据不是utf-8的格式就可以打印出信息进行转换对应的格式
这种是GBK格式,自行百度
最终实现的效果
手写客户端
import socket
# 创建socket对象
socket_client=socket.socket()
# 绑定ip地址和端口
socket_client.connect(("localhost",9999))
while True:
msg=input('请输入')
socket_client.send(msg.encode('UTF-8')) # 输入信息转换
recv_data=socket_client.recv(1024) # recv缓冲区1024即可 单线程阻塞
print(f'服务端返回的信息四{recv_data.decode("UTF-8")}')
socket_client.close()