函数的作用域和匿名函数、闭包、回调

函数,作用域,匿名,回调 · 浏览次数 : 4

小编点评

1. **函数定义**:函数是定义在程序中的代码片段,包含着函数的代码和执行逻辑。 2. **闭包**:闭包是函数里面嵌套函数的现象,外层函数可以访问嵌套函数的局部变量。 3. **递归**:递归是一种在函数自身定义的函数,并在每次执行时调用它本身的过程。 4. **回调函数**:回调函数是当一个函数被另一个函数中执行时,自动执行的函数。 5. **闭包与递归的区别**:闭包可以访问嵌套函数的局部变量,而递归是函数自身定义的函数,在每次执行时都会调用自身。

正文

一、匿名函数:

1、filter函数,可以过滤出列表中大于3的数据,但是使用都需要提前定义一个函数,有没有更加简便的方式呢?

def f(o):   # 过滤器
    if o>3:
        print(o)

list(filter(f,[3,1,5,9,7,10]))

运行截图:

 2、匿名函数(lambda后面是空格)

 

# lambda   参数 : 表达式
print(list(filter(lambda o:o>3,[3,1,5,9,7,10])))  # 不需要使用函数就能够完成

运行截图:  

二、函数作用域 

思考:

在函数里面也有可以定义变量,那函数里面的变量名如果和函数外面的变量名重名,会相互影响吗?

1、 函数里面可以访问外面的变量,但不可以修改

a=1 # 先声明变量 a  # 把外面的当做爸爸
def f():          # 儿子
    print(a)

f() 

运行截图:

 2、外部不能访问函数内部变量,函数里面和函数外部变量名可以相同,互相不影响

a=1  # 爸爸
def f():
    a=123
    print(a)

f()  # 123  # 函数里面有的这个变量就自己,外面的不可以访问函数里面的变量
print(a)  # 打印的是函数外面的a===函数里面和外面的相互不受影响

运行截图:

 3、函数里面不能修改函数外部变量

a = 1  # 爸爸
def f():  # 儿子
    a = a + 1  # 不可以改变爸爸的变量
    print(a)


f()  # 3  函数里面只可以访问不可以修改

运行截图:

 4. global(全局变量) 和 nonlocal(局部变量) 

a = 1  # 爸爸    ===称为全局变量
def f():  # 儿子  ===局部变量
    global a # 声明外面变量===外面的变量就发生了变化
    a = a + 1  # global 声明后可以改变爸爸的变量
    print(a)
    print(id(a))

f() 
print(a)
print(id(a))     # global声明后里外输出的值均为2,id也是一样的

运行截图:

 如果不声明全局变量,那么函数里面不能修改函数外部变量

 以上总结:局部的可以拿全局变量,全局不可以拿局部的。

5、 函数在什么时候执行?  

a=1
def f():
    a=2
    # 函数里面可以放任何东西
    def f2():
        a=3
        print(123)
#
f()  # 所以这样写f2函数不会执行
print(a)

运行截图:

调用f2() 才可以执行对应代码块 ==  (函数名+括号) 

a=1
def f():
    a=2
    # 函数里面可以放任何东西
    def f2():
        a=3
        print(123)
    f2()

f()  # 函数在什么时候执行?
# f2() 不可以这样写
print(a)

运行截图:

如果注释这里的变量值a就向上一级要值,儿子向=====》》》爸爸要值
a=1
def f():
a=2
print(a) # 2
# 函数里面可以放任何东西
def f2():
# a=3 # 如果注释这里的变量值a就向上一级要值 儿子=====》》》爸爸
print(a)
print(123)
f2()

f() # 函数在什么时候执行?(函数名+括号)
print(a)

运行截图:

 如果爸爸没有就向爷爷咨询要值 

a=1
def f():
    # a=2
    # print(a)  # 2  # 如果爸爸没有就向爷爷咨询要值 一层一层的取值
    # 函数里面可以放任何东西
    def f2():
        # a=3  # 如果注释这里的变量值a就向上一级要值 儿子==》》爸爸 如果爸爸没有就向爷爷咨询要值
        print(a)
        print(123)
    f2()

f()  # 函数在什么时候执行?(函数名+括号)  所以这样写f2函数不会执行
print(a)

运行截图:

 global a 全局变量的作用,改变外部函数参数值大小

a=1
def f():
    global a
    a=a+5
    print(a)  # 6
    # 函数里面可以放任何东西
    def f2():
        # a=3  #
        print(a) # 6
        print(123)
    f2()

f()  # 函数在什么时候执行?(函数名+括号)  
print(a)  # 6

运行截图:

 # 注释global a后:  

a=1
def f():
    # global a
    a=2
    print(a)  
    # 函数里面可以放任何东西
    def f2():
        # a=3  
        print(a) 
        print(123)
    f2()

f()  # 函数在什么时候执行?(函数名+括号)
print(a)

运行截图:

 nonlocal: 在函数嵌套函数的情况下,同样也有函数作用域的问题,但是python3中提供了方便,只需要使用nonlocal就可以在里层函数内部修改外部函数变量

a=1
def f():
    # global a
    a=2
    print(a)  
    # 函数里面可以放任何东西
    def f2():
        nonlocal a  # 声明局部(改变的是上级局部变量)
        # a=3  
        a=a+5
        # print(a)
        print(123)
    f2()
    print(a)
f()  # 函数在什么时候执行?  
print(a)

运行截图:

 global a # 声明全局变量 

a=1
def f():
    # global a
    a=2
    print(a)
    # 函数里面可以放任何东西
    def f2():
      
        global a  # 声明全局变量 
        # a=3  
        a=a+5
        print(a)
        print(123)
    f2()

f()  # 函数在什么时候执行?(函数名+括号)  所以这样写f2函数不会执行
print(a)

运行截图:

总结:

 

三、闭包

思考:函数里面可以再定义函数,那函数里面定义的函数可以在外面调用吗?如果可以的话,要怎么做呢?

'''
闭包是函数里面嵌套函数,外层函数返回里层函数,这种情况称之为闭包
闭包是概念,不是某种函数类型,和递归的概念类似,就是种特殊的函数调用
闭包可以得到外层函数的局部变量,是函数内部和函数外部沟通的桥梁

'''
例1:
def f():
    print('这里是f函数')
    def f2():

        print('这里是f2函数')
    return f2  # 返回的是f2 函数
    # return 123  # 返回的是123

a=f()   # a====f2函数  (函数名+括号) 代表调用
a() # 调用f2  闭包:外层函数返回内层函数
print(a) # 返回的是123
# print(f)

运行截图:

例2:

def f():
    print('这里是f函数')
    def f2():

        print('这里是f2函数')
    # return f2  # 返回的是f2 函数
    return 123  # 返回的是123

a=f()   # a====f2函数  (函数名+括号) 代表调用
# a() # 调用f2  闭包:外层函数返回内层函数
print(a) # 返回的是123

运行截图:

 例3:

def f():
    print('这里是f函数')
    def f2():

        b=1
        print('这里是f2函数')
        return b+2

    return f2  # 对于f2函数来说哪里调用的就返回哪里

a=f()   # a====f2函数  (函数名+括号) 代表调用 并传给a,由a接受
l=a()   # 代表调用f2  闭包:外层函数返回内层函数
print(l)

运行截图: 

 例4:

def fun(a):
    print(a)

    def fun1():
        print(a,11)

    return fun1  # 调用不行执

a = fun(3)
a()  #  相当于 fun(3)() 调用fun1

运行截图:

 

四、递归和回调函数

思考:

1、函数里面可以自身调用自身吗?

递归中可以函数自身调用自身,但是使用时类似于条件循环一样,要有递归的终止条件

递归应用:

使用递归时,常常可以让代码更加简洁 递归会占用比较多的内存,当递归次数比较多时,性能就会降低, 因此不建议多使用递归

例1:

递归:自己调用自己称为递归

def f(n):
    if n==1:
        return 1
    return f(n-1)*n
# 5*f(4)  5*4*f(3) 5*4*3*f(2) 5*4*3*2*f(1)
a=f(5)
print(a)

运行截图:

2、 回调函数:一个函数当做是一个参数传给另一个函数--- 称为回调

自身是一个函数,只是被传入到另一个函数当中,供其调用 回调函数不一定会被调用,是否调用由被传入函数的内部逻辑决定

例1:

def f():
    print('这里是f函数')   # f 为回调函数
def f2(o):
    print('这里是f2函数')
    # o为参数
    o()  # ====说明在调用f函数

f2(f)

运行截图:

 例2:

def f(a):
#     print(a)
#
# def f2(o):
#     print('这里是f2函数')
#     # o为参数
#     o(15)  # ====说明在调用f函数,哪里调用就在哪里传参!
#
# f2(f)

运行截图:

 

与函数的作用域和匿名函数、闭包、回调相似的内容:

函数的作用域和匿名函数、闭包、回调

一、匿名函数: 1、filter函数,可以过滤出列表中大于3的数据,但是使用都需要提前定义一个函数,有没有更加简便的方式呢? def f(o): # 过滤器 if o>3: print(o) list(filter(f,[3,1,5,9,7,10])) 运行截图: 2、匿名函数(lambda后面是空

Java 方法引用

目录定义使用条件使用方式匿名类lambda 表达式::引用已有方法总结 定义 将方法作为参数传递即为方法引用。 以@FunctionalInterface 修饰的接口 其中只能有一个抽象方法。 这个抽象方法的形参和返回值便是对所引用方法的约束。 使用条件 引用方法的返回值类型和形参需要与函数式接口的

4.0 Python 变量与作用域

在python中,变量的作用域决定了变量在哪些位置可以被访问。一个程序中的变量并不是所有的地方都可以访问的,其访问权限决定于变量的赋值位置。python中有两种最基本的变量作用域:局部作用域和全局作用域。局部变量是在函数内部定义的变量,只能在其被声明的函数内部访问。而全局变量则是在函数外定义的变量,可以在整个程序的范围内被访问。局部变量只有在其被声明的函数内部才能被访问,全局变量则可以在程序的任何

[转帖]【JVM】堆内存与栈内存详解

堆和栈的定义 java把内存分成栈内存和堆内存。 (1)栈内存 在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配。 当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空间,当超过变量的作用域后,java会自动释放掉为该变量分配的内存空间,该内存空间可以立刻被另

Python常见面试题001-005,涉及深浅拷贝、MRO、函数可变参数、作用域、is和==的区别等

Python常见面试题001-005 参考资料 https://github.com/taizilongxu/interview_python https://github.com/hantmac/Python-Interview-Customs-Collection https://github.

函数基础和函数参数

第一部分:函数基础 函数的作用意义: 1.为了更好地管理代码,可能对应的代码块需要重复多次使用,所以通过一个函数封装起来,便于下次直接调用 2.方法实际上是通过函数实现的 例1: # type() # 内置函数 def lis(): li=[1,2,3] li.append(4) li.pop(2)

#PowerBI 1分钟学会,利用format函数,自定义格式显示

PowerBI是一款强大的数据分析和可视化工具,它可以帮助我们快速地创建各种报表和仪表盘,展示数据的洞察和价值。 在PowerBI中,有许多内置的函数可以帮助我们处理和转换数据,其中一个常用的函数就是Format函数。 Format函数的作用是将一个值按照指定的格式进行显示,例如日期、时间、货币、百

驱动开发:内核无痕隐藏自身分析

在笔者前面有一篇文章`《驱动开发:断链隐藏驱动程序自身》`通过摘除驱动的链表实现了断链隐藏自身的目的,但此方法恢复时会触发PG会蓝屏,偶然间在网上找到了一个作者介绍的一种方法,觉得有必要详细分析一下他是如何实现的驱动隐藏的,总体来说作者的思路是最终寻找到`MiProcessLoaderEntry`的入口地址,该函数的作用是将驱动信息加入链表和移除链表,运用这个函数即可动态处理驱动的添加和移除问题。

算法金 | Python 中有没有所谓的 main 函数?为什么?

​大侠幸会,在下全网同名[算法金] 0 基础转 AI 上岸,多个算法赛 Top [日更万日,让更多人享受智能乐趣] 定义和背景 在讨论Python为何没有像C或Java那样的明确的main函数之前,让我们先理解一下什么是main函数以及它在其他编程语言中的作用。 在C和C++等语言中,main函数是

整理C语言预处理过程语法的实用方法与技巧

预处理 目录预处理一、宏定义数值宏常量字符串宏常量用define宏定义注释符号?程序的编译过程预处理中宏替换和去注释谁先谁后?如何写一个不会出现问题的宏函数do-while-zero结构do-while-zero的评价宏定义中的空格宏只能在main函数上面定义吗?宏的作用范围#undef宏替换是在函