八、python-高级语法篇(黑马程序猿-python学习记录)

news2024/12/27 13:57:23

黑马程序猿的python学习视频:https://www.bilibili.com/video/BV1qW4y1a7fU/

===============================================================

目录

1. 什么是闭包

2. 闭包的优缺点

3. nonlocal关键字的作用

4. 简单闭包

5. 使用nonlocal关键字修改外部函数的值

6. 使用闭包实现ATM小案例

7. 装饰器概念

8. 装饰器的一般写法

9. 装饰器的快捷写法-语法糖

10. 设计模式

​​​​​​​11. 单例模式

12. 工厂模式

13. 什么是进程

14. 什么是线程

15. 什么是并行执行

16. 演示多线程

17. 多线程传参

18. Socket概念

19. Socket连接-聊天效果

20. Socket-服务端开发

21. socket-客户端开发

22. 递归


1. 什么是闭包

定义双层嵌套函数,内层函数可以访问外层函数的变量

将内存函数作为外层函数的返回,此内存函数就是闭包函数

2. 闭包的优缺点

优点:

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

缺点:

  1. 由于内部函数持续引用外部函数的值,所以会导致这一部分内存空间不被释放,一直占用内存。

3. nonlocal关键字的作用

在闭包函数(内部函数)中想要修改外部函数的变量值

需要用nonlocal声明这个外部变量

4. 简单闭包

# 简单闭包

def outer(logo):

def inner(msg):

print(f"<{logo}>{msg}<{logo}>")

return inner

fn1 = outer("啦啦");

fn1("新年好呀")

<啦啦>新年好呀<啦啦>

5. 使用nonlocal关键字修改外部函数的值

# 使用nonlocal关键字膝盖外部函数的值

def outer(num1):

def inner(num2):

nonlocal num1

num1+=num2

print(num1)

return inner

fn1 = outer(20);

fn1(1)

21

6. 使用闭包实现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

atm = account_create()

atm(100)

atm(200)

atm(100,deposit=False)

存款:+100,账户余额100

存款:+200,账户余额300

取款:-100,账户余额:200

7. 装饰器概念

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

8. 装饰器的一般写法

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

def sleep():

import random

import time

print("睡眠中")

time.sleep(random.randint(1,5))

def outer(func):

def inner():

print("我睡觉了")

func()

print("我起床了")

return inner

fn = outer(sleep)

fn()

我睡觉了

睡眠中

我起床了

9. 装饰器的快捷写法-语法糖

# 装饰器的快捷写法(语法糖)

from numpy import outer

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

我睡觉了

睡眠中

我起床了

10. 设计模式

设计模式是一种编程套路,可以极大地方便程序的开发。

最常见,最经典的设计模式,就是我们所学习的面向对象了。

除了面向对象外,在编程中也有很多既定的套路可以方便开发,我们称之为设计模式:

  1. 单例模式,工厂模式
  2. 建造者、责任链、状态、备忘录、解释器、访问者、观察者、中介、模板、代理模式
  3. 等等模式

​​​​​​​11. 单例模式

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

定义:保证一个类只有一个实例,并提供一个访问他的全局访问点

适用场景:当一个类只能有一个实例,而客户可以从一个众所周知的访问点访问他时。

单例模式就是对一个类,只获取其唯一 类实例对象,持续复用他。

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

12. 工厂模式

概念:将对象的创建由使用原生类本身创建,转换到由特定的工厂方法来创建

好处:

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

造人工厂实例如下

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

student=pf.get_person("s")

teacher=pf.get_person("t")

13. 什么是进程

程序在操作系统内运行,即成为一个运行进程

14. 什么是线程

进程内部可以有多个线程,程序的运行本质上就是由进程内部的线程在实际工作的

15. 什么是并行执行

多个进程同时在运行,即不同的程序同时运行,称之为:多任务并行执行

一个进程内的多个线程同时在运行,称之为:多线程并行执行

16. 演示多线程

import time

import threading

def sing():

while True:

print("我在唱歌....")

time.sleep(1)

def dance():

while True:

print("我在跳舞....")

time.sleep(1)

if __name__ =='__main__':

# 创建一个唱歌的线程

sing_thread = threading.Thread(target=sing)

# 创建一个跳舞的线程

dance_thread = threading.Thread(target=dance)

# 让线程干活吧

sing_thread.start()

dance_thread.start()

我在唱歌....

我在跳舞....

我在跳舞....我在唱歌....

我在跳舞....我在唱歌....

我在跳舞....我在唱歌....

我在跳舞....我在唱歌....

17. 多线程传参

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__':

# 创建一个唱歌的线程

sing_thread = threading.Thread(target=sing,args=("我在唱歌..",))

# 创建一个跳舞的线程

dance_thread = threading.Thread(target=dance,kwargs={"msg":"我在跳舞.."})

# 让线程干活吧

sing_thread.start()

dance_thread.start()

我在唱歌..

我在跳舞..

我在唱歌..

我在跳舞..

我在跳舞..我在唱歌..

18. Socket概念

 

19. Socket连接-聊天效果

服务端

客户端

D:\python\python.exe D:\qwb\workspace\myworkspace_python\01python入门\23socket服务端.py

接收到了客户端的链接,客户端的信息是:('127.0.0.1', 55012)

客户端发来的消息是:在呢

请输入你要和客户端回复的消息:我也在的

客户端发来的消息是:在干嘛呢

请输入你要和客户端回复的消息:关你屁事

客户端发来的消息是:你大爷的 滚吧

请输入你要和客户端回复的消息:exit

进程已结束,退出代码0

D:\python\python.exe D:\qwb\workspace\myworkspace_python\01python入门\24Socket客户端.py

请输入要给服务器发送的消息:在呢

服务端回复的消息是:我也在的

请输入要给服务器发送的消息:在干嘛呢

服务端回复的消息是:关你屁事

请输入要给服务器发送的消息:你大爷的 滚吧

服务端回复的消息是:

请输入要给服务器发送的消息:exit

进程已结束,退出代码0

20. Socket-服务端开发

"""

演示Socket服务端开发

"""

import socket

# 创建Socket对象

socket_server = socket.socket()

# 绑定ip地址和端口

socket_server.bind(("localhost", 8888))

# 监听端口

# listen方法内接收一个整数 传参数 ,表示接收的链接数量

socket_server.listen(1)

# 等待客户端链接

# accept方法返回的是二元元组(连接对象,客户端的地址信息) conn:客户端和服务端的链接 address:客户端的地址信息

# 可以通过 变量1,变量2=socket_server.accept()的形式,直接接受二元元组的两个元素

# accept方法 ,是阻塞的方法,等待客户端的链接,如果没有链接,就卡在这一步 不向下执行了

conn,address = socket_server.accept()

print(f"接收到了客户端的链接,客户端的信息是:{address}")

while True:

# 接收客户端消息,要使用客户端和服务端的本次链接对象,而非socket_server对象

data = conn.recv(1024).decode("UTF-8")

# recv接收的参数是缓冲区大小,一般是1024即可

# recv方法的返回值是一个字节数组 也就是bytes对象,不是字符串,可以通过decode方法通过UTF-8编码,将字节数组转换为字符串对象

print(f"客户端发来的消息是:{data}")

msg = input("请输入你要和客户端回复的消息:")

# 如果服务端输入exit,断开连接

if(msg=='exit'):

break

# 发送回复消息

# encode方法可以将字符串编码为字节数组对象

conn.send(msg.encode("UTF-8"))

# 关闭连接

conn.close()

socket_server.close()

21. socket-客户端开发

"""

演示socket客户端开发

"""

import socket

# 创建socket对象

socket_client = socket.socket()

# 连接到服务器

socket_client.connect(("localhost",8888))

while True:

msg = input("请输入要给服务器发送的消息:")

if msg=='exit':

break

# 发送消息

socket_client.send(msg.encode("UTF-8"))

# 接收返回消息

# 1024是缓冲区的大小 一般1024即可。同样recv是阻塞方法

recv_data = socket_client.recv(1024)

print(f"服务端回复的消息是:{recv_data.decode('UTF-8')}")

# 关闭连接

socket_client.close()

22. 递归

什么是递归:在满足条件的情况下,函数自己调用自己 一种特殊编程技巧

递归需要注意什么:注意退出的条件,否则容易变成无限递归

注意返回值的传递,确保从最内层,层层传递到最外层

os模块的3个方法

os.listdir,列出指定目录下的内容

os.path.isdir,判断给定路径是否是文件夹,是的话返回True,否的话返回False

os.path.exists,判断给定路径是否存在,存在返回True,不存在返回False

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/177985.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vue-Router详解

1、前端路由的发展历程 1.1、认识前端路由 路由其实是网络工程中的一个术语&#xff1a; 在架构一个网络时&#xff0c;非常重要的两个设备就是路由器和交换机。当然&#xff0c;目前在我们生活中路由器也是越来越被大家所熟知&#xff0c;因为我们生活中都会用到路由器&…

算法:树状数组详解(c++实现 求解动态数组区间和问题)

文章目录引入树状数组c完整代码引入 什么是树状数组&#xff1f;&#xff1f;&#xff1f; 解决数据压缩里的累积频率&#xff08;Cumulative Frequency&#xff09;的计算问题&#xff0c;现多用于高效计算数列的前缀和&#xff0c; 区间和&#xff0c;这样的问题可以使用树…

Day8 spring 注解开发

1 前言使用注解类代替xml配置&#xff0c;使用注解代理xml中的标签2 标签2.1 用于Bean(类)上的常见注解2.1.1 Component步骤&#xff1a;在xml中配置包扫描&#xff0c;使得spring知道在哪些类上加上Component在特定类上加上Component测试/*** author : msf* date : 2023/1/24*…

#I. 哆啦A梦的时光机(bfs经典习题)

题目说明有一天&#xff0c;大雄和他的伙伴们想穿越时空进行探险&#xff0c;可是时光机却出了一点故障&#xff0c;只能进行有限的时空穿越操作。大雄他们需要从现在出发&#xff0c;到达一个目标时间点进行探险&#xff0c;结束后再返回到现在&#xff0c;他们希望尽可能减少…

Linux——网络编程概述

Q&#xff1a;为什么要网络编程&#xff1f;A&#xff1a;进程间的通信是依赖于Linux内核的&#xff0c;只能适用于单机&#xff0c;而要实现联机&#xff0c;就要用网络编程&#xff0c;网络编程是面向多台设备间的通信网络编程两个重要概念&#xff1a;IP地址和端口&#xff…

微服务拆分之道

背景 微服务在最近几年大行其道&#xff0c;很多公司的研发人员都在考虑微服务架构&#xff0c;同时&#xff0c;随着 Docker 容器技术和自动化运维等相关技术发展&#xff0c;微服务变得更容易管理&#xff0c;这给了微服务架构良好的发展机会。 在做微服务的路上&#xff0…

JavaWeb | JDBC相关API详解 1(含源码阅读)

本专栏主要是记录学习完JavaSE后学习JavaWeb部分的一些知识点总结以及遇到的一些问题等&#xff0c;如果刚开始学习Java的小伙伴可以点击下方连接查看专栏 本专栏地址&#xff1a;&#x1f525;JDBC Java入门篇&#xff1a; &#x1f525;Java基础学习篇 Java进阶学习篇&#x…

5、常量与变量

目录 1.数值型变量 &#xff08;1&#xff09;整型常量 &#xff08;2&#xff09;实型常量 2.字符型常量 (1)字符常量 (2) 字符串常量 3. ASCII表 4. 转义符号 5.符号常量 6. 整型变量 &#xff08;1&#xff09;有符号基本整型 &#xff08;2&#xff09;无符号基…

JavaScript Break 和 Continue 语句

文章目录JavaScript Break 和 Continue 语句Break 语句Continue 语句JavaScript 标签笔记列表JavaScript Break 和 Continue 语句 break 语句用于跳出循环。 continue 用于跳过循环中的一个迭代。 Break 语句 我们已经在本教程之前的章节中见到过 break 语句。它用于跳出 swi…

final的一个重要用途-宏变量和未初始化问题

/*** author 张家琛* version 1.0* date 2023/1/24 20:23*/ public class FinalDemo {public static void main(String[] args) {final var a5;System.out.println(a);} } 对于上面的程序来说&#xff0c;变量a其实根本就不存在&#xff0c;这段代码本质上执行的是转换成的&am…

MyBatis知识点笔记

目录 mybatis mapper-locations的作用&#xff1f; mybatis configuration log-impl 作用&#xff1f; resultType和resultMap的区别&#xff1f; 参数 useGeneratedKeys &#xff0c;keyColumn&#xff0c;keyProperty作用和用法 取值方式#和$区别 动态标签有哪些 MyBat…

字节青训前端笔记 | Vite 入门

本节课&#xff0c;讲师将前置介绍有关前端工程基本知识&#xff0c;同时讲解前端构建工具及解决问题&#xff0c;进而引出作为前端构建工具的 Vite 是什么及其在开发过程中的应用。 为什么使用构建工具 前端是有一系列资源组成的&#xff0c;js 代码&#xff0c;css样式&…

ESP32 Micropython编程(Thonny)04---- 人体感应模块

本人持续分享更多关于嵌入式和单片机的知识&#xff0c;如果大家喜欢&#xff0c;别忘点个赞加个关注哦&#xff0c;让我们一起共同进步 最近使用到人体感应模块HC-SR501&#xff0c;这个模块使用十分简单&#xff0c;看下面代码就可以看出了&#xff0c;而且应用广泛&#xff…

Java 优先级队列(堆)

目录1. 优先级队列&#xff08;堆&#xff09;的概念2. 建立大根堆&#xff08;向下调整算法&#xff09;3. 堆插入元素&#xff08;向上调整算法&#xff09;4. 堆删除元素&#xff08;向下调整算法&#xff09;5. 优先级队列PriorityQueue的特性6. 优先级队列PriorityQueue的…

单向环形链表和约瑟夫问题

单向环形链表和约瑟夫问题 Josephu 问题为&#xff1a;设编号为1&#xff0c;2&#xff0c;… n的n个人围坐一圈&#xff0c;约定编号为k&#xff08;1<k<n&#xff09;的人从1开始报数&#xff0c;数到m 的那个人出列&#xff0c;它的下一位又从1开始报数&#xff0c;数…

ubuntu压缩、归档 tar zip gzip的介绍

不同文件需要使用不同的工具进行压缩和解压&#xff0c;可以使用file文件查看是什么类型的文件 file 文件名如图&#xff0c;在第二行看到这个文件是gzip类型的。 文件&#xff1a;gzip 工具&#xff1a;gunzip gunzip是 gnu unzip的缩写。用来解压gzip压缩包。 解压命令 …

linux 内存管理

0.前言 1.了解Linux内存的管理机制(分段分页) 2.了解虚拟内存和物理内存的映射方式 3.了解操作系统内存与磁盘的交互&#xff08;分页机制---》缺页重读机制&#xff0c;用时拷贝机制) 4.应用程序如何高效使用内存和高级程序的设计方法 1.linux物理使用情况 内核区&#x…

动态站点地图提交百度收录

站点地图&#xff08;sitemap&#xff09;是一个网站的结构化数据&#xff0c;搜索引擎可以通过站点地图迅速了解一个网站的内容&#xff0c;加快搜索引擎收录。 一般来说&#xff0c;站点地图是以.xml结尾的静态化文件&#xff0c;例如个人博客和生化环材网的站点地图链接分别…

【Mysql】事务的四大特性(ACID)

【Mysql】事务的四大特性(ACID) 文章目录【Mysql】事务的四大特性(ACID)1. 概述1.1 并发事务问题1.1.1 脏读1.1.2 不可重复读1.1.3 幻读1.2 事务隔离级别1. 概述 事务的四大特性&#xff1a; 原子性&#xff08;Atomicity&#xff09;&#xff1a;事务是不可分割的最小操作单…

ROS学习寄录2

1 ROS核心概念 1.1 节点&#xff08;Node&#xff09; &#xff08;1&#xff09;执行具体任务的进程、独立运行的可执行文件 &#xff08;2&#xff09;不同节点可以使用不同的语言&#xff0c;可分布式运行在不同的主机 &#xff08;3&#xff09;节点在系统中的名称必须…