欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 维修 > python函数-进阶

python函数-进阶

2024/11/30 6:36:20 来源:https://blog.csdn.net/W030321/article/details/139837018  浏览:    关键词:python函数-进阶
大纲概览
  1. 闭包与装饰器
    • 闭包:一个内部函数,它包含了对外部函数作用域(非全局作用域)中变量的引用。
    • 装饰器:一种在不修改原函数代码的情况下,给函数增加额外功能的技术。
  1. 生成器
    • 生成器是迭代器的一种,但它只在迭代到该元素时才计算该元素的值,而不是一次性生成所有元素。
    • 使用yield关键字创建生成器。
  1. 序列化
    • 序列化:将数据结构或对象状态转换为可以存储或传输的形式的过程。
    • 反序列化:是序列化的逆过程,即将序列化后的形式转换回数据结构或对象状态。
闭包与装饰器
  1. 闭包示例
    • f1()函数是闭包函数,它调用了func()并将func()的返回值加1后返回。
    • f2()函数用于创建闭包,接受一个函数作为参数并返回一个新的函数。
  1. 装饰器
    • 装饰器使用@符号将装饰器函数与被装饰函数联系起来。
    • 示例中,f2是一个装饰器函数,它接受一个函数作为参数并返回一个新函数f1,f1会调用原函数func并添加额外功能。
  1. 装饰器改进
    • 使用@符号使得装饰器更加简洁和易于使用。
生成器
  1. 生成器基础
    • 使用yield关键字定义生成器函数。
    • 调用生成器函数时,它不会立即执行函数体,而是返回一个生成器对象。
    • 使用next()函数或for循环来迭代生成器对象,每次迭代执行到yield语句时,会暂停并返回yield后面的值。
  1. 示例

def func():  print("111")  yield 222  gener = func()  # 获取生成器对象  
ret = gener.__next__()  # 执行生成器,获取第一个yield的值  
print(ret)  # 输出: 222
文档提及
  1. JSON
    • json.dumps(obj):将Python对象转换为JSON字符串。
    • json.loads(s):将JSON字符串转换为Python对象。
    • json.dump(obj, file):将Python对象写入文件,并转换为JSON格式。
    • json.load(file):从文件中读取JSON数据,并转换为Python对象。
  1. Pickle
    • 用于Python特有的类型(如自定义类)和Python数据类型间的转换。
    • 与JSON相比,pickle支持更多Python数据类型,但生成的序列化数据不可读,且不是跨语言的。
函数进阶

1. 间接调用函数

  • 直接调用函数:直接使用函数名加参数列表调用函数。
  • 间接调用函数:
    • 将函数名赋值给变量,再通过变量名加形参列表调用。
    • 一个函数作为另一个函数的参数。
    • 函数名作为其他数据类型的元素(如列表、字典等)。

2. 匿名函数

  • 匿名函数:没有函数名称的临时微函数,使用lambda表达式声明。
  • 语法格式:lambda [arg1, arg2, ..., argn]: expression
  • 应用场景:当函数只有一个返回值且只有一句代码时,使用lambda简化。
  • 注意:lambda表达式只能包含一个表达式,且必须有返回值,但可以调用其他函数。

3. 生成器

  • 生成器与函数的区别:在函数中使用yield代替return,函数就变成了生成器函数。
  • 执行生成器函数时,不会立即执行函数体,而是返回一个生成器对象。
  • 使用next()方法或迭代访问生成器中的元素,每次调用next()或迭代时,生成器会执行到下一个yield语句并返回其值。
  • 生成器是惰性求值的,即按需生成数据,不会一次性加载所有数据到内存中,节省内存。

4. send()与next()方法

  • send()和next()方法都可以使生成器执行到下一个yield语句。
  • send()可以向上一个yield的位置传递值(但不能给最后一个yield发送值),next()则没有此功能。
  • 第一次执行生成器代码时,不能使用send()方法,应使用next()启动生成器。

示例代码

# 示例1:匿名函数  
sum_func = lambda x, y: x + y  
print(sum_func(3, 5))  # 输出:8  # 示例2:生成器  
def fibonacci():  a, b = 0, 1  while True:  yield a  a, b = b, a + b  fib = fibonacci()  
print(next(fib))  # 输出:0  
print(next(fib))  # 输出:1  # 示例3:send()与next()  
def eat():  print("我吃什么?")  a = yield "馒头"  print("a=", a)  b = yield "大饼"  print("b=", b)  c = yield "韭菜盒子"  print("c=", c)  yield "GAME OVER"  gen = eat()  
print(next(gen))  # 输出:"我吃什么?" 和 "馒头"  
print(gen.send("胡辣汤"))  # 输出:"a=胡辣汤" 和 "大饼"  
print(gen.send("狗粮"))  # 输出:"b=狗粮" 和 "韭菜盒子"
1. 生成器与迭代器
  • 生成器:通过yield关键字定义的函数,称为生成器函数。执行生成器函数时,不会立即执行函数体中的代码,而是返回一个生成器对象。这个对象是一个迭代器,可以通过next()方法或for循环逐个获取其中的值。
  • 迭代器:迭代器是一种可以记住遍历的位置的对象。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
2. 生成器的使用
  • 使用next()方法:调用生成器对象的__next__()方法(通常简写为next())可以获取生成器中的下一个值。如果生成器已经遍历完所有的值,再次调用next()会抛出StopIteration异常。
  • 使用for循环:由于生成器是一个迭代器,因此可以直接使用for循环遍历生成器中的值,无需手动调用next()方法。
3. send()方法
  • send()方法是生成器特有的一个方法,它的功能与next()类似,都可以让生成器执行到下一个yield语句。但send()方法可以向生成器发送一个值,这个值会被上一个yield表达式接收。
  • 注意:在第一次执行生成器代码时,不能使用send()方法,应使用next()或for循环来启动生成器。
4. 生成器表达式与列表推导式
  • 生成器表达式:使用圆括号()包围的推导式,它返回的是一个生成器对象,而不是列表。生成器表达式在需要时才计算生成值,因此更加节省内存。
  • 列表推导式:使用方括号[]包围的推导式,它返回的是一个列表。列表推导式会一次性生成所有的值,因此会占用更多的内存。
5. 示例代码
  • 生成器函数示例
def eat():  print("我吃什什么啊")  a = yield "馒头"  print("a=", a)  b = yield "大饼"  print("b=", b)  c = yield "韭菜盒子"  print("c=", c)  yield "GAME OVER"  gen = eat()  
print(next(gen))  # 输出: 馒头  
print(gen.send("胡辣汤"))  # 输出: 大饼  
print(gen.send("狗粮"))  # 输出: 韭菜盒子
  • 生成器表达式示例
# 生成一个从1到5的平方的生成器  
squares = (x**2 for x in range(1, 6))  
for square in squares:  print(square)  # 输出: 1, 4, 9, 16, 25
6. 总结
  • 生成器提供了一种高效的方式来处理大量数据,它们只会在需要时才生成值,从而节省了大量的内存空间。
  • 迭代器和生成器是Python中处理序列数据的重要工具,它们提供了一种灵活的方式来遍历和操作数据。
  • send()方法为生成器提供了与上一个yield位置交互的能力,使得生成器在处理数据时更加灵活。
  • 生成器表达式和列表推导式在语法上非常相似,但它们在内存使用和处理方式上有着显著的区别。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com