python:函数

一、嵌套函数

1.1概念

嵌套函数是定义在另一个函数作用域内部的函数。外部函数可以访问其内部声明的嵌套函数,而嵌套函数则可以访问其外部函数的作用域(包括参数和局部变量)。

1.2实例

一般情况下,我们是这样书写嵌套函数的,通过funA来访问funB

def funA():
    x=123;
    def funB():
        print(x)
    funB()
funA()

这里我们也可以把funB()修改为return funB

这样当funA被调用时,他不会立即执行funB,而是返回funB函数对象的引用。这意味着你可以将funB作为一个值传递给其他函数或者稍后调用它

一般情况下,当我们执行完funny=funA()之后,funA内的局部变量就会被释放,但我们通过funny()仍然可以访问x的值,这就说明外层变量被保存下来了,没有释放,这就是我们接下来要说的闭包

def funA():
    x=123;
    def funB():
        print(x)
    return funB
#调用funB
funA()()
#funA得到的事funB函数的一个引用
#当我们不想通过funA来调用funB时,就可以把funA赋值给一个变量
funny=funA()
funny()

这里要注意,在第五行中我们要写return funB,千万不要写成return funB()

return funB:表示返回funB函数对象本身,而不是调用,因此当外层的 funA函数执行到return funB时,返回的是funB函数的一个引用

return funB():表示调用funB函数,并返回它的执行结果,而在funB函数中没有return函数,所以默认返回None,因此当funA执行return funB()时,它实际上返回的是None,然后你把funA的返回值赋值给变量funny,然后通过funny()想调用funB,会造成TypeError,因为NoneType对象是不可以调用的

二、函数闭包(closure)

2.1定义

一般情况下,在外层函数执行结束之后,局部变量会被回收,如果有内部函数仍然需要访问这些变量,Python解释器会保留这些变量的引用,直到内部函数不再需要它们为止。

2.2实例

调用square来实现平方,调用cube来实现立方

def power(exp):
    def exp_of(base):
        print(base ** exp)
    return exp_of
square=power(2)
cube=power(3)
square(3)
cube(2)

三、nonlocal

  • 用于嵌套函数中申明对外层函数中局部变量的引用或修改
  • 允许嵌套函数修改外层函数中的变量
在嵌套函数中,我们在内层函数中申明一个变量,必须对他进行初始化,那每次调用该函数时,每次输出的值都是在初始化值的基础上+1

3.1实例1

def out():
    count=0
    def inner():
        nonlocal count
        count +=1
        print(f"count={count}")
    return inner
funny=out()
funny()
funny()

3.2实例2

def outer():
    x=0
    y=0
    def inner(x1,y1):
        nonlocal x,y
        x+=x1
        y+=y1
        print(f"现在 x=({x},y={y})")
    return inner
move=outer()
move(1,2)
move(-2,2)

四、global

  • 用于在函数内部生命一个变量是全部变量,而不是局部变量
  • 允许函数内部修改全局变量的值
这里我们想让count的值每次做到能累加,而不是每次从初始化值开始

4.1实例1

count = 0
def out():
    def inner():
        global count
        count+=1
        print(f"count={count}")
    return inner
funny=out()
funny()
funny()

五、装饰器(decorator)

5.1定义

装饰器的工作原理:自动将装饰器语法后紧挨着的函数作为参数传递给装饰器函数(这个过程是隐式的),并返回一个新的函数

应用装饰器:使用@将装饰器应用于目标函数或方法

调用目标函数:当前目标函数被调用时,实际上执行的是装饰器返回的新函数

5.2实例

5.2.1装饰器

import time

def time_decorator(func):
    def call_func():
        print("start...")
        start=time.time()
        func()
        stop=time.time()
        print("stop...")
        print(f"spend {(stop-start):.2f}s")
    return call_func

#使用装饰器
@time_decorator
def myfunc():
    time.sleep(2)
    print("hello world")

myfunc()

还原就是这样

import time

def time_decorator(func):
    def call_func():
        print("start...")
        start=time.time()
        func()
        stop=time.time()
        print("stop...")
        print(f"spend {(stop-start):.2f}s")
    return call_func
def myfunc():
    time.sleep(2)
    print("hello world")

myfunc=time_decorator(myfunc)
myfunc()

5.2.2 多个装饰器同时用在同一个函数上

调用顺序为cube->square->add

def add(func):
    def inner():
        x=func()
        return x+1
    return inner

def square(func):
    def inner():
        x=func()
        return x*x
    return inner

def cube(func):
    def inner():
        x=func()
        return x*x*x
    return inner

@add
@square
@cube
def test():
    return 2

print(test())

还原就是这样

def add(func):
    def inner():
        x=func()
        return x+1
    return inner

def square(func):
    def inner():
        x=func()
        return x*x
    return inner

def cube(func):
    def inner():
        x=func()
        return x*x*x
    return inner

def test():
    return 2

#这里的func1是一个新的函数
func1=cube(test)
#再将func1传入到square中
func2=square(func1)
func3=add(func2)
func1()
func2()
x=func3()
print(x)

5.2.3给装饰器传递参数

import time

def logger(msg):
    def time_func(func):
        def call_func():
            start=time.time()
            func()
            stop=time.time()
            print(f"[{msg}]speed{(stop-start):.2f}s")
        return call_func
    return time_func

@logger(msg='A')
def funA():
    time.sleep(1)
    print("调用funA...")

@logger(msg='B')
def funB():
    time.sleep(1)
    print("调用funB...")

funA()
funB()

还原就是这样

import time

def logger(msg):
    def time_func(func):
        def call_func():
            start=time.time()
            func()
            stop=time.time()
            print(f"[{msg}]speed{(stop-start):.2f}s")
        return call_func
    return time_func
    
def funA():
    time.sleep(1)
    print("调用funA...")

def funB():
    time.sleep(1)
    print("调用funB...")

funA=logger('A')(funA)
funB=logger('B')(funB)

funA()
funB()

六、列表推导式

6.1定义

列表推导式是一种从现有列表或其他可迭代对象中创建新列表的简洁方法。它允许你使用循环和条件表达式来生成列表,而无需编写完整的循环语句。

6.1.1语法

[expression for item in iterable if condition]
  • expression:这是你想要生成列表中每个元素的表达式。
  • item:这是当前正在处理的迭代项。
  • iterable:这是你想要从中生成列表的可迭代对象,如列表、元组、字符串或任何其他可迭代对象。
  • condition(可选):这是一个可选的条件表达式,用于确定哪些项应该被包含在最终列表中。只有满足条件的项才会被包括。

6.2实例

6.2.1 生成一个0-9的平方的列表

square =[x*x for x in range(10)]
print(square)

6.2.2 将字符串转换为大写/小写

strings=["hello","world"]
upper_strings=[s.upper() for s in strings]
print(upper_strings)

strings1=["PYTHON","BETTER"]
upper_strings1=[s.lower() for s in strings1]
print(upper_strings1)

6.2.3嵌套列表

matrix=[[1,2,3],[4,5,6],[7,8,9]]
change=[[row[i] for row in matrix] for i in range(len(matrix[0]))]
print(change)

展开是这样的

matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
transposed = []  # 初始化一个空列表,用于存储转置后的矩阵

# 外层循环遍历列索引
for i in range(len(matrix[0])):
    # 为每一列创建一个新列表
    column = []
    # 内层循环遍历所有行
    for row in matrix:
        # 将当前行的第i个元素添加到column列表中
        column.append(row[i])
    # 将这一列添加到转置后的矩阵中
    transposed.append(column)

# 输出转置后的矩阵
print(transposed)

七、生成器(generator)

7.1定义

用于创建迭代器的特殊函数。它们允许你一次生成一个值,而不是一次性将所有值加载到内存中

7.2使用

  • 生成器函数使用yield关键字而不是return来返回值
  • 每次调用生成器的__next__()方法(或者通过next()函数)时,它会执行到下一个yield语句,并返回相应的值。生成器函数会在遇到yield时暂停执行,并在下次调用时从暂停的地方继续执行。

7.3实例

7.3.1简单使用生成器

def counter():
    i=0
    while i<=5:
        yield i#每次调用到该语句就生成一个新数据
        i+=1

for i in counter():
    print(i,end=' ')

7.3.2使用next()函数

def counter():
    i=0
    while i<=5:
        yield i#每次调用到该语句就生成一个新数据
        i+=1

c=counter()
print(next(c))
print(next(c))

当访问越界之后就会报错

生成器每次只会生成一个对象,所以也不能使用下标访问

def counter():
    i=0
    while i<=5:
        yield i#每次调用到该语句就生成一个新数据
        i+=1

c=counter()
print(c[2])

7.3.2使用生成器打印斐波那契数列

def fib():
    back1,back2=0,1
    while True:
        yield back1
        back1,back2 = back2,back1+back2

f=fib()
for i in f:
    if(i>1000):
        break
    print(i)

但这里要注意一个问题

下面的代码这样写是有问题的,会陷入无限循环,因为外部for循环迭代的是生成器f,它会不断产生新的斐波那契数,而内部的while循环则设置了要小于10000,然而外部循环没有终止条件,它将永远持续下去,即使内部的while循环在某次迭代后不再执行,外部循环仍然会要求生成器产生下一个数字

def fib():
    back1,back2=0,1
    while True:
        yield back1
        back1,back2 = back2,back1+back2

f=fib()
for i in f:
    while(i<1000):
        print(i,end=' ')

7.4生成器表达式

生成器表达式语法与列表推导式非常相似,但不同之处在于生成器表达式使用()而不是[]

t=(i**2 for i in range(10))
for i in t:
    print(i,end=' ')

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux 下的 GPT 和 MBR 分区表详解

文章目录 Linux 下的 GPT 和 MBR 分区表详解一、分区表的作用二、MBR&#xff08;Master Boot Record&#xff09;1. **特点**2. **优点**3. **缺点**4. **适用场景** 三、GPT&#xff08;GUID Partition Table&#xff09;1. **特点**2. **优点**3. **缺点**4. **适用场景** 四…

基于单片机的智能婴儿床监护系统多功能婴儿床摇篮系统

功能介绍 以STM32单片机为控制核心蓝牙传输控制可以进行哭闹检测、尿床检测、音乐播放、语音提醒、哭闹时可以进行摇床有不同的模式自动模式和睡眠模式 实物可做&#xff0c;其他功能也可以 电路图 PCB 源代码 u8 Temperature_High; //室内温度高阈值 u8 Temperature_…

人工智能在VR展览中扮演什么角色?

人工智能&#xff08;AI&#xff09;在VR展览中扮演着多重关键角色&#xff0c;这些角色不仅增强了用户体验&#xff0c;还为展览的组织者提供了强大的工具。 接下来&#xff0c;由专业从事VR展览制作的圆桌3D云展厅平台为大家介绍AI在VR展览中的一些主要作用&#xff1a; 个性…

JVM和数据库面试知识点

JVM内存结构 主要有几部分&#xff1a;堆、栈、方法区和程序计数器 堆是JVM中最大的一块内存区域&#xff0c;用于存储对象实例&#xff0c;一般通过new创建的对象都存放在堆中。堆被所有的线程共享&#xff0c;但是它的访问时线程不安全的&#xff0c;通常通过锁的机制来保证线…

flask-admin+Flask-WTF 实现实现增删改查

背景&#xff1a; flask-adminflask-wtf在网上可以搜索到很多资料&#xff0c;但有价值的很少&#xff0c;或许是太简单&#xff0c;或者是很少人这么用&#xff0c;或者。。。&#xff0c;本文将作者近礼拜摸索到的一点经验分享出来&#xff0c;给自己做个记录。 材料&#…

C++简明教程(文章要求学过一点C语言)(3)

一、编程工具大揭秘——IDE 当我们准备踏入 C 编程的奇妙世界时&#xff0c;首先要认识一个重要的“魔法盒子”——集成开发环境&#xff08;IDE&#xff09;。IDE 就像是一个全能的编程工作室&#xff0c;它把我们写代码所需要的各种工具都整合到了一起&#xff0c;让编程这件…

STM32-笔记5-按键点灯(中断方法)

1、复制03-流水灯项目&#xff0c;重命名06-按键点灯&#xff08;中断法&#xff09; 在\Drivers\BSP目录下创建一个文件夹exti&#xff0c;在该文件夹下&#xff0c;创建两个文件exti.c和exti.h文件&#xff0c;并且把这两个文件加载到项目中&#xff0c;打开项目工程文件 加载…

实现 WebSocket 接入文心一言

目录 什么是 WebSocket&#xff1f; 为什么需要 WebSocket&#xff1f; HTTP 的局限性 WebSocket 的优势 总结&#xff1a;HTTP 和 WebSocket 的区别 WebSocket 的劣势 WebSocket 常见应用场景 WebSocket 握手过程 WebSocket 事件处理和生命周期 WebSocket 心跳机制 …

leetcode-80.删除有序数组的重复项II-day12

总结&#xff1a;不必过于死磕一道题目&#xff0c;二十分钟没做出来就可参考题解

RTOS之邮箱

邮箱 邮箱 (Mailbox) 服务是实时操作系统中一种常用的线程间通信机制。它提供了一种高效、低开销的消息传递方式&#xff0c;允许线程之间交换固定大小的数据。 1. 邮箱的应用场景 考虑一个简单的示例&#xff1a;线程 1 负责检测按键状态并将状态信息发送出去&#xff0c;线程…

凯酷全科技抖音电商服务的卓越践行者

在数字经济蓬勃发展的今天&#xff0c;电子商务已成为企业增长的新引擎。随着短视频平台的崛起&#xff0c;抖音作为全球领先的短视频社交平台&#xff0c;不仅改变了人们的娱乐方式&#xff0c;也为品牌和商家提供了全新的营销渠道。厦门凯酷全科技有限公司&#xff08;以下简…

AI的进阶之路:从机器学习到深度学习的演变(三)

&#xff08;承接上集&#xff1a;AI的进阶之路&#xff1a;从机器学习到深度学习的演变&#xff08;二&#xff09;&#xff09; 四、深度学习&#xff08;DL&#xff09;&#xff1a;机器学习的革命性突破 深度学习&#xff08;DL&#xff09;作为机器学习的一个重要分支&am…

数据集-目标检测系列 车牌检测识别 数据集 CCPD2019

车牌检测&识别 数据集 CCPD2019 DataBall 助力快速掌握数据集的信息和使用方式&#xff0c;会员享有 百种数据集&#xff0c;持续增加中。 需要更多数据资源和技术解决方案&#xff0c;知识星球&#xff1a; “DataBall - X 数据球(free)” 贵在坚持&#xff01; 数据样…

安全算法基础(一)

安全算法是算法的分支之一&#xff0c;还的依靠大量的数学基础进行计算&#xff0c;本文参照兜哥的AI安全样本对抗&#xff0c;做一个简单的算法安全概括&#xff0c;从零学习。 最新的安全算法对于我们常规的攻击样本检测&#xff0c;效果是不理想的&#xff0c;为了探究其原…

[SZ901]JTAG高速下载设置(53Mhz)

SZ901最高支持JTAG 53MHz的时钟频率&#xff0c;下载bit文件和固化程序的速度提升非常明显。 首先设置参数 1&#xff0c;将JTAG0 分频系数修改为3 2&#xff0c;设置参数&#xff0c;更新参数。&#xff08;完成&#xff09; 打开VIVADO VIVADO 正常识别FPGA&#xff0c;速…

图漾相机-ROS1_SDK_ubuntu版本编译(新版本)

文章目录 官网编译文档链接官网SDK下载链接1、下载 Camport ROS1 SDK1.下载git2、下载链接 2、准备编译工作1、安装 catkin2、配置环境变量3. 将Camport3中的linux库文件拷贝到 user/lib目录下4、修改lunch文件制定相机&#xff08;可以放在最后可以参考在线文档&#xff09;**…

openbmc hwmon与sensor监控

1.说明 参考文档: https://github.com/openbmc/entity-manager/blob/master/docs/entity_manager_dbus_api.mdhttps://github.com/openbmc/entity-manager/blob/master/docs/my_first_sensors.md 1.1 简单介绍 注意: 本节是快速浏览整个sensor框架&#xff0c;了解大致open…

Java --- 多线程

目录 前言&#xff1a; 一.线程的创建&#xff1a; 1.通过继承 Thread 类来创建线程&#xff1a; 2.通过Runnable接口创建线程&#xff1a; 3.通过Java8引入的lambda语法&#xff1a; 线程的优先级&#xff1a; 二.线程的生命周期&#xff1a; 三. 中断线程&#xff1a…

使用 acme.sh 申请域名 SSL/TLS 证书完整指南

使用 acme.sh 申请域名 SSL/TLS 证书完整指南 简介为什么选择 acme.sh 和 ZeroSSL&#xff1f;前置要求安装过程 步骤一&#xff1a;安装 acme.sh步骤二&#xff1a;配置 ZeroSSL 证书申请 方法一&#xff1a;手动 DNS 验证&#xff08;推荐新手使用&#xff09;方法二&#xf…

Flutter组件————Scaffold

Scaffold Scaffold 是一个基础的可视化界面结构组件&#xff0c;它实现了基本的Material Design布局结构。使用 Scaffold 可以快速地搭建起包含应用栏&#xff08;AppBar&#xff09;、内容区域&#xff08;body&#xff09;、抽屉菜单&#xff08;Drawer&#xff09;、底部导…