python进阶:函数

一、函数

<一>、变量作用域

  • 和其它语言类似,若是在函数内部定义的,就称为局部变量,只在函数内部有效,一旦函数执行完毕,局部变量就会被回收,无法访问
  • 函数内部可以访问外部的全局变量,直接修改会报错,若要修改,需加上global关键字(不建议做),如下述代码所示,这里的global并不表示重新创建了全局变量value,而是告诉python解释器,函数内部的value就是之前定义的全局变量
value = 10
def value_modify():
	global value
	value += 1
	print(value)

value_modify()
  • 对于嵌套函数来说,内部函数可以访问外部函数定义的变量,但是无法修改,若要修改,必须加上nonlocal关键字,如下述代码所示,内部和外部函数打印出来的变量应该是一致的,
def outer():
	x = 'local'
	def inner():
		nonlocal x
		x = 'nonlocal'
		print('inner:',x)
	inner()
	print('outer:',x)

outer()

<二>、函数常见的几种形式

  • 在python中,函数是第一公民,函数也是对象,可以为函数赋予变量
def func(message):
	print('got a message: {}'.format(message))

get_message = func
get_message('hello qinshihuang')

如上述代码所示,把函数func赋予了变量get_message,这样,调用get_message相当于调用func

  • 可以把函数当作参数,传入另一个函数中
def get_message(message):
	print('got a message: {}'.format(message))

def call_message(func,message):
	print(func(message))

#调用
call_message(get_message,'hello qinshihuang')
  • 嵌套函数,也就是函数里定义函数
def func(message):
	def get_message(message):
		print('got a message: {}'.format(message))
	return get_message(message)

func('hello qinshihuang')

如上述代码所示,在函数func()中又定义了新的函数get_message(),调用后作为函数func()的返回值返回

二、闭包

  • 闭包就是函数的返回值是函数对象
  • 更详细的说就是在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数引用,这样就构成了闭包,外层函数的参数,不一定要有,看情况而定,但是一般情况下都会有并且被内函数使用到
def testClosure():
	def get_message(message):
		print('got a message: {}'.format(message))
	return get_message

get_message = testClosure()
get_message('hello qinshihuang')

如上述代码所示,testClosure为外部函数,get_message为内部函数,外函数的返回值是内函数的引用
再看下面这个例子

def nth_power(exponent):
	def exponent_of(base):
		return base ** exponent
	return exponent_of

#调用
square = nth_power(2)
cube = nth_power(3)
print(square(2)) #计算2的平方
print(cube(3)) #计算3的立方

如上述代码所示,外部函数nth_power()返回值,是函数exponent_of(),而不是一个具体的数值,需要注意的是在执行square = nth_power(2)和cube = nth_power(3)后,外部函数的参数exponent仍然会被内部函数exponent_of()记住
这也是闭包的一个特性:一般情况下,如果一个函数结束,函数内部的所有东西都会释放掉,还给内存,局部变量都会消失闭包是一种特殊情况

闭包是一种特殊情况,如果外函数在结束的时候发现有自己的临时变量将来还会在内部函数中用到,就把这个临时变量绑定给了内部函数,然后自己再结束

闭包的作用
闭包理解起来还是比较绕的,而且闭包实现的功能,用其它的方式也能实现,为什么要用闭包呢?我谈谈个人的理解

  • 合理地使用闭包,可以简化程序的复杂度,提高可读性
    如上面的求立方、平方的函数,不用闭包就是下述形式
def nth_power(base,exponent):
	return base ** exponent

#调用
res1 = nth_power(base1,2)
res2 = nth_power(base2,3)
  • 装饰器:Python的装饰器是用闭包实现的,装饰器
  • 面向对象:使用闭包的时候,总是和类联系在一起,外部函数的变量相当于实例化类的时候传的属性,内部函数就相当于类中的方法,这样看来,闭包也是实现面向对象的方法之一

三、匿名函数

  • 形式
lambda arg1,arg2 ... argn : expression
#求某个数的平方,用匿名函数表示
square = lambda x : x ** 2

如上述代码所示,匿名函数以lambda开始,之后是一系列的参数,然后用冒号隔开,最后是由这些参数的表达式

  • lambda是一个表达式,并不是一个语句
  • lambda的主体是只有一行简单的表达式,并不能扩展一个多行的代码块,这其实是出于设计的考虑,python之所以发明lambda,就是为了让它和常规函数各司其职:lambda专注于简单的任务,而常规函数则负责更复杂的多行逻辑

1、为什么要使用匿名函数?

  • 理论上来说,python中有匿名函数的地方,都可以被替换成等价的其它表达形式,一个Python程序是可以不用任何匿名函数的,不过,在一些情况下,使用lambda,可以帮助我们大大简化代码的复杂度,提高代码可读性

eg:

#匿名函数
square = map(lambda x: x**2,[1,2,3,4,5])
#常规函数
def square(x):
	return x ** 2

square = map(square,[1,2,3,4,5])
  • 28
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我爱夜来香A

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值