跨境互联网 跨境互联网
首页
  • AI 工具

    • 绘图提示词工具 (opens new window)
    • ChatGPT 指令 (opens new window)
  • ChatGPT

    • ChatGP T介绍
    • ChatGPT API 中文开发手册
    • ChatGPT 中文调教指南
    • ChatGPT 开源项目
  • Midjourney

    • Midjourney 文档
  • Stable Diffusion

    • Stable Diffusion 文档
  • 其他

    • AIGC 热门文章
    • 账号合租 (opens new window)
    • 有趣的网站
  • Vue

    • Vue3前置
  • JAVA基础

    • Stream
    • Git
    • Maven
    • 常用第三方类库
    • 性能调优工具
    • UML系统建模
    • 领域驱动设计
    • 敏捷开发
    • Java 测试
    • 代码规范及工具
    • Groovy 编程
  • 并发编程&多线程

    • 并发编程
    • 高性能队列 Disruptor
    • 多线程并发在电商系统下的应用
  • 其他

    • 面试题
  • 消息中间中间件

    • Kafka
    • RabbitMQ
    • RocketMQ
  • 任务调度

    • Quartz
    • XXL-Job
    • Elastic-Job
  • 源码解析

    • Mybatis 高级使用
    • Mybatis 源码剖析
    • Mybatis-Plus
    • Spring Data JPA
    • Spring 高级使用
    • Spring 源码剖析
    • SpringBoot 高级使用
    • SpringBoot 源码剖析
    • Jdk 解析
    • Tomcat 架构设计&源码剖析
    • Tomcat Web应用服务器
    • Zookeeper 高级
    • Netty
  • 微服务框架

    • 分布式原理
    • 分布式集群架构场景化解决方案
    • Dubbo 高级使用
    • Dubbo 核心源码剖析
    • Spring Cloud Gateway
    • Nacos 实战应用
    • Sentinel 实战应用
    • Seata 分布式事务
  • 数据结构和算法的深入应用
  • 存储

    • 图和Neo4j
    • MongoDB
    • TiDB
    • MySQL 优化
    • MySQL 平滑扩容实战
    • MySQL 海量数据存储与优化
    • Elasticsearch
  • 缓存

    • Redis
    • Aerospike
    • Guava Cache
    • Tair
  • 文件存储

    • 阿里云 OSS 云存储
    • FastDF 文件存储
  • 基础

    • Linux 使用
    • Nginx 使用与配置
    • OpenResty 使用
    • LVS+Keepalived 高可用部署
    • Jekins
  • 容器技术

    • Docker
    • K8S
    • K8S
  • 01.全链路(APM)
  • 02.电商终极搜索解决方案
  • 03.电商亿级数据库设计
  • 04.大屏实时计算
  • 05.分库分表的深入实战
  • 06.多维系统下单点登录
  • 07.多服务之间分布式事务
  • 08.业务幂等性技术架构体系
  • 09.高并发下的12306优化
  • 10.每秒100W请求的秒杀架构体系
  • 11.集中化日志管理平台的应用
  • 12.数据中台配置中心
  • 13.每天千万级订单的生成背后痛点及技术突破
  • 14.红包雨的架构设计及源码实现
  • 人工智能

    • Python 笔记
    • Python 工具库
    • 人工智能(AI) 笔记
    • 人工智能(AI) 项目笔记
  • 大数据

    • Flink流处理框架
  • 加密区

    • 机器学习(ML) (opens new window)
    • 深度学习(DL) (opens new window)
    • 自然语言处理(NLP) (opens new window)
AI 导航 (opens new window)

Revin

首页
  • AI 工具

    • 绘图提示词工具 (opens new window)
    • ChatGPT 指令 (opens new window)
  • ChatGPT

    • ChatGP T介绍
    • ChatGPT API 中文开发手册
    • ChatGPT 中文调教指南
    • ChatGPT 开源项目
  • Midjourney

    • Midjourney 文档
  • Stable Diffusion

    • Stable Diffusion 文档
  • 其他

    • AIGC 热门文章
    • 账号合租 (opens new window)
    • 有趣的网站
  • Vue

    • Vue3前置
  • JAVA基础

    • Stream
    • Git
    • Maven
    • 常用第三方类库
    • 性能调优工具
    • UML系统建模
    • 领域驱动设计
    • 敏捷开发
    • Java 测试
    • 代码规范及工具
    • Groovy 编程
  • 并发编程&多线程

    • 并发编程
    • 高性能队列 Disruptor
    • 多线程并发在电商系统下的应用
  • 其他

    • 面试题
  • 消息中间中间件

    • Kafka
    • RabbitMQ
    • RocketMQ
  • 任务调度

    • Quartz
    • XXL-Job
    • Elastic-Job
  • 源码解析

    • Mybatis 高级使用
    • Mybatis 源码剖析
    • Mybatis-Plus
    • Spring Data JPA
    • Spring 高级使用
    • Spring 源码剖析
    • SpringBoot 高级使用
    • SpringBoot 源码剖析
    • Jdk 解析
    • Tomcat 架构设计&源码剖析
    • Tomcat Web应用服务器
    • Zookeeper 高级
    • Netty
  • 微服务框架

    • 分布式原理
    • 分布式集群架构场景化解决方案
    • Dubbo 高级使用
    • Dubbo 核心源码剖析
    • Spring Cloud Gateway
    • Nacos 实战应用
    • Sentinel 实战应用
    • Seata 分布式事务
  • 数据结构和算法的深入应用
  • 存储

    • 图和Neo4j
    • MongoDB
    • TiDB
    • MySQL 优化
    • MySQL 平滑扩容实战
    • MySQL 海量数据存储与优化
    • Elasticsearch
  • 缓存

    • Redis
    • Aerospike
    • Guava Cache
    • Tair
  • 文件存储

    • 阿里云 OSS 云存储
    • FastDF 文件存储
  • 基础

    • Linux 使用
    • Nginx 使用与配置
    • OpenResty 使用
    • LVS+Keepalived 高可用部署
    • Jekins
  • 容器技术

    • Docker
    • K8S
    • K8S
  • 01.全链路(APM)
  • 02.电商终极搜索解决方案
  • 03.电商亿级数据库设计
  • 04.大屏实时计算
  • 05.分库分表的深入实战
  • 06.多维系统下单点登录
  • 07.多服务之间分布式事务
  • 08.业务幂等性技术架构体系
  • 09.高并发下的12306优化
  • 10.每秒100W请求的秒杀架构体系
  • 11.集中化日志管理平台的应用
  • 12.数据中台配置中心
  • 13.每天千万级订单的生成背后痛点及技术突破
  • 14.红包雨的架构设计及源码实现
  • 人工智能

    • Python 笔记
    • Python 工具库
    • 人工智能(AI) 笔记
    • 人工智能(AI) 项目笔记
  • 大数据

    • Flink流处理框架
  • 加密区

    • 机器学习(ML) (opens new window)
    • 深度学习(DL) (opens new window)
    • 自然语言处理(NLP) (opens new window)
AI 导航 (opens new window)
  • Python介绍
  • 基础

  • 进阶

    • Python模块与包
    • Python面向对象
    • Python面向对象高级
    • Python高级语法
      • with语句和上下文管理器
        • with语句
      • 生成器的创建方式
        • 生成器推导式
        • yield生成器
        • yield关键字和return关键字
        • 为什么要使用yield生成器
        • yield与斐波那契数列
      • 深浅拷贝
        • 几个概念
        • 赋值
        • 浅拷贝
        • 深拷贝
        • 案例演示
    • Python正则表达式
    • Python进程和线程
    • Python闭包与装饰器
  • 其他

  • Python开源项目
  • Python
  • 进阶
Revin
2023-04-16
目录

Python高级语法

# with语句和上下文管理器

# with语句

Python提供了 with 语句的写法,既简单又安全。

文件操作的时候使用with语句可以自动调用关闭文件操作,即使出现异常也会自动关闭文件操作。

举个栗子:

image-20230416170605078

使用with方法实现文件操作,如下所示:

# 1、以写的方式打开文件
with open('1.txt', 'w') as f:
    # 2、读取文件内容
    f.write('hello world')
1
2
3
4

# 生成器的创建方式

根据程序设计者制定的规则循环生成数据,当条件不成立时则生成数据结束

数据不是一次性全部生成出来,而是使用一个,再生成一个,可以节约大量的内存。

创建生成器的方式

  • ① 生成器推导式

  • ② yield 关键字

# 生成器推导式

与列表推导式类似,只不过生成器推导式使用小括号。

# 创建生成器
my_generator = (i * 2 for i in range(5))
print(my_generator)

# next获取生成器下一个值
# value = next(my_generator)
# print(value)

# 遍历生成器
for value in my_generator:
    print(value)
1
2
3
4
5
6
7
8
9
10
11

生成器相关函数:

next 函数获取生成器中的下一个值
for  循环遍历生成器中的每一个值 
1
2

# yield生成器

yield 关键字生成器的特征:在def函数中具有yield关键字

def generator(n):
    for i in range(n):
        print('开始生成...')
        yield i
        print('完成一次...')
        
g = generator(5)
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))				----->    正常
print(next(g))  			----->    报错
Traceback (most recent call last):
  File "/Users/cndws/PycharmProjects/pythonProject/demo.py", line 14, in <module>
    print(next(g))
StopIteration
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def generator(n):
    for i in range(n):
        print('开始生成...')
        yield i
        print('完成一次...')
        
g = generator(5)
for i in g:
    print(i)
1
2
3
4
5
6
7
8
9
def generator(n):
    for i in range(n):
        print('开始生成...')
        yield i
        print('完成一次...')
        
g = generator(5)
while True:
    try:
        print(next(g))
    except StopIteration:
        break
1
2
3
4
5
6
7
8
9
10
11
12

注意点:

① 代码执行到 yield 会暂停,然后把结果返回出去,下次启动生成器会在暂停的位置继续往下执行

② 生成器如果把数据生成完成,再次获取生成器中的下一个数据会抛出一个StopIteration 异常,表示停止迭代异常

③ while 循环内部没有处理异常操作,需要手动添加处理异常操作

④ for 循环内部自动处理了停止迭代异常,使用起来更加方便,推荐大家使用。

# yield关键字和return关键字

如果不太好理解yield,可以先把yield当作return的同胞兄弟来看,他们都在函数中使用,并履行着返回某种结果的职责。

这两者的区别是:

有return的函数直接返回所有结果,程序终止不再运行,并销毁局部变量;

def example():
    x = 1
    return x

example = example()
print(example)
1
2
3
4
5
6

而有yield的函数则返回一个可迭代的 generator(生成器)对象,你可以使用for循环或者调用next()方法遍历生成器对象来提取结果。

def example():
    x = 1
    y = 10
    while x < y:
        yield x
        x += 1

example = example()
print(example)
1
2
3
4
5
6
7
8
9

image-20230416170724726

# 为什么要使用yield生成器

import memory_profiler as mem


# nums = [1, 2, 3, 4, 5]
# print([i*i for i in nums])


nums = list(range(10000000))
print('运算前内存:', mem.memory_usage())
# 列表
# square_nums = [n * n for n in nums]
# 生成器
square_nums = (n * n for n in nums)
print('运算后内存:', mem.memory_usage())
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# yield与斐波那契数列

数学中有个著名的斐波拉契数列(Fibonacci)

要求:数列中第一个数为0,第二个数为1,其后的每一个数都可由前两个数相加得到:

例子:1, 1, 2, 3, 5, 8, 13, 21, 34, ...

现在我们使用生成器来实现这个斐波那契数列,每次取值都通过算法来生成下一个数据, 生成器每次调用只生成一个数据,可以节省大量的内存。

def fib(max): 
    n, a, b = 0, 0, 1 
    while n < max: 
        yield b      # 使用 yield
        # print b 
        a, b = b, a + b 
        n = n + 1
 
for n in fib(5): 
    print n
1
2
3
4
5
6
7
8
9
10

# 深浅拷贝

# 几个概念

  • 变量:是一个系统表的元素,拥有指向对象的连接空间
  • 对象:被分配的一块内存,存储其所代表的值
  • 引用:是自动形成的从变量到对象的指针
  • 类型:属于对象,而非变量
  • 不可变对象:一旦创建就不可修改的对象,包括数值类型、字符串、布尔类型、元组

(该对象所指向的内存中的值不能被改变。当改变某个变量时候,由于其所指的值不能被改变,相当于把原来的值复制一份后再改变,这会开辟一个新的地址,变量再指向这个新的地址。)

  • 可变对象:可以修改的对象,包括列表、字典、集合

(该对象所指向的内存中的值可以被改变。变量(准确的说是引用)改变后,实际上是其所指的值直接发生改变,并没有发生复制行为,也没有开辟新的地址,通俗点说就是原地改变。)

当我们写:

a = "python"
1

Python解释器干的事情:

① 创建变量a

② 创建一个对象(分配一块内存),来存储值 'python'

③ 将变量与对象,通过指针连接起来,从变量到对象的连接称之为引用(变量引用对象)

image-20230416170813095

# 赋值

赋值: 只是复制了新对象的引用,不会开辟新的内存空间。

并不会产生一个独立的对象单独存在,只是将原有的数据块打上一个新标签,所以当其中一个标签被改变的时候,数据块就会发生变化,另一个标签也会随之改变。

image-20230416170828977

# 浅拷贝

浅拷贝: 创建新对象,其内容是原对象的引用。

浅拷贝之所以称为浅拷贝,是它仅仅只拷贝了一层,拷贝了最外围的对象本身,内部的元素都只是拷贝了一个引用而已。

案例1:赋值

image-20230416170844561

案例2:可变类型浅拷贝

image-20230416170854835

案例3:不可变类型浅拷贝

image-20230416170906029

注:不可变类型进行浅拷贝不会给拷贝的对象开辟新的内存空间,而只是拷贝了这个对象的引用

浅拷贝有三种形式: 切片操作,工厂函数,copy模块中的copy函数。

如: lst = [1,2,[3,4]]

切片操作:lst1 = lst[:] 或者 lst1 = [each for each in lst]

注:[:]它与[0:]相似,意思是从0索引拆分到末尾。它返回一个新列表。

工厂函数:lst1 = list(lst)

copy函数:lst1 = copy.copy(lst)

但是在lst中有一个嵌套的list[3,4],如果我们修改了它,情况就不一样了。

浅复制要分两种情况进行讨论:

1)当浅复制的值是不可变对象(字符串、元组、数值类型)时和“赋值”的情况一样,对象的id值*(id()函数用于获取对象的内存地址)*与浅复制原来的值相同。

2)当浅复制的值是可变对象(列表、字典、集合)时会产生一个“不是那么独立的对象”存在。有两种情况:

第一种情况:复制的对象中无复杂子对象,原来值的改变并不会影响浅复制的值,同时浅复制的值改变也并不会影响原来的值。原来值的id值与浅复制原来的值不同。

第二种情况:复制的对象中有复杂子对象(例如列表中的一个子元素是一个列表),如果不改变其中复杂子对象,浅复制的值改变并不会影响原来的值。 但是改变原来的值中的复杂子对象的值会影响浅复制的值。

# 深拷贝

深拷贝:和浅拷贝对应,深拷贝拷贝了对象的所有元素,包括多层嵌套的元素。深拷贝出来的对象是一个全新的对象,不再与原来的对象有任何关联。

所以改变原有被复制对象不会对已经复制出来的新对象产生影响。只有一种形式,copy模块中的deepcopy函数。

可变类型深拷贝:

image-20230416170922438

不可变类型深拷贝:不可变类型进行深拷贝不会给拷贝的对象开辟新的内存空间,而只是拷贝了这个对象的引用

image-20230416170938004

# 案例演示

案例1:对于可变对象深浅拷贝

import copy
a=[1,2,3]

print("=====赋值=====")
b=a
print(a)
print(b)
print(id(a))
print(id(b))

print("=====浅拷贝=====")
b=copy.copy(a)
print(a)
print(b)
print(id(a))
print(id(b))

print("=====深拷贝=====")
b=copy.deepcopy(a)
print(a)
print(b)
print(id(a))
print(id(b))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

结果:

=====赋值=====
[1, 2, 3]
[1, 2, 3]
37235144
37235144
=====浅拷贝=====
[1, 2, 3]
[1, 2, 3]
37235144
37191432
=====深拷贝=====
[1, 2, 3]
[1, 2, 3]
37235144
37210184
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

小结:

赋值: 值相等,地址相等

copy浅拷贝:值相等,地址不相等

deepcopy深拷贝:值相等,地址不相等

案例2:对于可变对象深浅拷贝(外层改变元素)

import copy
l=[1,2,3,[4, 5]]

l1=l #赋值
l2=copy.copy(l) #浅拷贝
l3=copy.deepcopy(l) #深拷贝
l.append(6)

print(l)  
print(l1)
print(l2)
print(l3)
1
2
3
4
5
6
7
8
9
10
11
12

结果:

[1, 2, 3, [4, 5], 6]     #l添加一个元素6
[1, 2, 3, [4, 5], 6]     #l1跟着添加一个元素6
[1, 2, 3, [4, 5]]        #l2保持不变
[1, 2, 3, [4, 5]]        #l3保持不变
1
2
3
4

案例3:对于可变对象深浅拷贝(内层改变元素)

import copy
l=[1,2,3,[4, 5]]

l1=l #赋值
l2=copy.copy(l) #浅拷贝
l3=copy.deepcopy(l) #深拷贝
l[3].append(6) 

print(l) 
print(l1)
print(l2)
print(l3)
1
2
3
4
5
6
7
8
9
10
11
12

结果:

[1, 2, 3, [4, 5, 6]]      #l[3]添加一个元素6
[1, 2, 3, [4, 5, 6]]      #l1跟着添加一个元素6
[1, 2, 3, [4, 5, 6]]      #l2跟着添加一个元素6
[1, 2, 3, [4, 5]]         #l3保持不变
1
2
3
4

小结:

① 外层添加元素时,浅拷贝不会随原列表变化而变化;内层添加元素时,浅拷贝才会变化。 ② 无论原列表如何变化,深拷贝都保持不变。 ③ 赋值对象随着原列表一起变化。

上次更新: 2025/04/03, 11:07:08
Python面向对象高级
Python正则表达式

← Python面向对象高级 Python正则表达式→

最近更新
01
tailwindcss
03-26
02
PaddleSpeech
02-18
03
whisper
02-18
更多文章>
Theme by Vdoing | Copyright © 2019-2025 跨境互联网 | 豫ICP备14016603号-5 | 豫公网安备41090002410995号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式