python中的函数(二)

本文深入探讨Python中的函数类型,包括自定义函数、匿名函数、传入函数、闭包及变量作用域等内容。解析不同函数的特点与应用场景,如lambda表达式的高效性和闭包的特殊作用,以及变量在局部、闭包、全局和内置作用域中的查找规则。

1.函数类型

函数也是一种类型,我们自定义的函数就是函数对象,函数名保存了函数对象的引用(地址)

def test():
    print('我是测试函数')

print(test)  #函数名是变量,指向了函数对象
pf = test    #pf变量也指向了函数对象,所以也可以通过pf调用test函数
pf()

2. 匿名函数

不再使用def 函数名()这种形式定义函数,而是使用lambda来创建匿名函数
特点:

  • lambda只是一个表达式,函数体比def定义的函数简单的多
  • lambda的函数体不再是代码块,而是一个表达式
  • lambda只有一行,运行效率很高
语法:lambda [arg1,arg2....argn]:表达式(只能是一个表达式)
add = lambda a,b:a + b
print(add(3,5))

3.传入函数

一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数,也可以称之为传入函数。可以实现通用编程,排序等复杂功能

#传入函数,高阶函数
def add(a,b):
	return a + b
def compute(a,b,func):
	return func(a,b)
#调用
compute(3,5,add)

# 系统函数callable可以用于检测变量是否可执行
if callable(func):
	func()  #可以执行,则执行函数

4.闭包

我们可以在一个函数中再定义一个函数,在函数内部定义的函数称之为内部函数,内部函数只能在函数内使用,不会污染外部空间。定义内部函数的函数称之为外部函数,这样的定义构成函数的嵌套

def outter(a): #外部函数
    x = 10
    def inner(y):  #内部函数
        print(x + y)
    inner(a)
    
outter(20)
  • 内部函数只能在外部函数里调用,外界无法直接调用内部函数
    在一个外部函数中定义了一个内部函数,内部函数里引用了外部函数的变量,并且外部函数的返回值是内函数的引用。这样内部函数和其执行所需的环境变量就构成了一个闭包。
    一般情况下,如果一个函数结束,函数的内部所有东西都会释放掉,局部变量都会消失。但是闭包是一种特殊情况,如果外函数在结束的时候发现有自己的局部变量将来会在内部函数中用到,就把这个局部变量绑定给了内部函数,然后自己再结束。
def outter(a): #外部函数
    x = a
    def inner(y):  #内部函数
        return x + y  #引用外部变量
    return inner  #返回内部函数(闭包)
pf = outter(20)
print(pf(10))  #30
print(pf(20))  #40

5.变量的作用域

程序中的变量并不是在任意的位置都可以随意访问,在哪里可以访问取决于这个变量的作用域,变量的作用域指的是变量在那段代码中可以使用,可以使用变量的那段代码就是变量的作用域。在python中,只有函数/类/模块才引入作用域,if/elif/else , while/for,try/except等并不会引入新的作用域

#if语句不引入新作用域,msg在外面可以使用
if True:
    msg = "message"

print(msg)
5.1 变量作用域的分类

按照作用域划分,可以分为:

  • L:Local,局部作用域
  • E:Enclosing,闭包作用域【闭包的外部函数中定义的变量】
  • G:Global,全局作用域 在所有函数外定义的变量
  • B:Built-in,內建作用域【内置作用域】
#1 局部作用域  
#局部变量只能在函数内部使用,外部无法引用
#局部变量的作用域从定义开始到函数体结束
def demo():
    num = 20  #局部变量  
    print(num)
demo()
#print(num) 错误

#闭包作用域
def outter():
   x = 10   #函数作用域,从定义开始到本函数结束
   def inner():
      y = x  #在闭包中可以引用
      print(y)
   return inner
pf = outter()
pf()  #执行闭包
print(pf.__closure__)

#全局作用域
x = 100    #全局作用域  从定义开始到本文件结束
def demo():
   print(x)
print(x)

#内建作用域,是指系统内建的函数或常量,在系统载入时加载,在所有模块中都可以直接引用
#比如说系统函数
print(max(1,2,3))  #max函数就是内建作用域  哪里都可以引用
def  demo():
    x = 30
    y = 50
    print(max(x, y))
5.2 变量作用域查找规则

以 L --> E --> G -->B 的规则查找,即:在局部找不到,便会去局部外的局部找(例如闭包),再找不到就会去全局找,最后到内建作用域中找。

5.3 全局变量和局部变量
  • 定义在函数内部的变量拥有一个局部作用域,被称为局部变量
  • 定义在函数外面的变量拥有一个全局作用域,被称为全局变量
  • 局部变量和全局变量同名,局部优先
total = 0   #全局变量
def sum(arg1,arg2):
    total = arg1 + arg2   #局部变量
    print("函数内部:",total)
    return total
    
sum(10,20)
#print(total1)
print("函数外部:",total)

num = 1
def fun1():
    print(num) #UnboundLocalError: local variable 'num' referenced before assignment
    num = 123
    print(num)

fun1()

5.4 global和nonlocal

#1.在Python中,当内部作用域想修改全局变量的时候,则就要使用global关键字进行声明
num = 1
def fun1():
    global num   #告诉编译器,此处的num是全局变量
    print(num)   #1
    num = 123
    print(num)  #123
    
fun1()

a = 10
def test():
    global  a
    a = a + 1
    print(a)
test()

#2.如果要修改闭包作用域中的变量,则使用nonlocal
#需要明确的是,nonlocal关键字定义在闭包里面
x = 0  #全局作用域

def outer():
    x = 1   #闭包作用域

    def inner():
        nonlocal x
        x = 2   #局部作用域
        print("inner:",x)  #2

    inner()
    print("outer:",x)  #1---->2

outer()
print("全局:",x)  #0

#nonlocal关键字:声明了该变量不只是在outer函数中有效,在inner函数内部也有效
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值