python的函数学习之路

函数

OK,终于在学习python的路上又迈出了一步,话不多说,开始冲刺吧。

函数的作用

先讲一下函数的功能,理解一下为什么要用函数。当我们在写代码的时候,难免要写很多重复的代码。用复制粘贴吧,看这个写的代码,自己内心深处难免会觉得Low.但是不写吧 ,功能又实现不了,那我们怎么办呢?这个时候,函数就有用武之地了。函数最主要的好处就是减少重复代码。在定义之后,只需要在需要用到的地方进行调用就好了。最大程度地减少了代码的重复率,还显得有B格。

函数的基础语法

万丈高楼平地起,老套路了,说一下函数的语法表现。

def 函数名(参数):
	代码功能
	return

函数在用def关键字来定义一个函数,在函数名后的括号里可以传递各种各样的参数。
函数在遇到return后,无论return后有什么代码,函数都会终止运行,并返回return后的值,当函数里没有return时,默认返回None。

函数内变量的作用域

变量分为全局变量(L)和局部变量(G)。

  • 全局变量就是程序在刚开始运行的时候就定义好的量,一直到程序结束。作用域为整个程序。
  • 局部变量是在函数内部定义的变量,当函数运行的时候生效,函数运行结束的时候变量就不在生效,作用域为函数内部。

当在函数内部出现变量的使用时,会先在内部变量里查找,然后才是去找全局变量。举个栗子,如果全局变量和局部变量都有name,在函数内部调用name时会优先使用局部变量的name。

name = "Jerry"

def test():
	name = "Tom"
	print("%s run" % name)
test()
# 输出结果为  Tom run

def test():
	global name
	name = "Tom"
	print("%s run" % name)
test()
print(name)
# 此时输出的结果为  Tom run 和 Tom

global的作用是在函数内部声明一个全局变量,将一个局部变量变成全局变量。但是不推荐使用,对于程序的维护会造成困扰。

如果全局变量是一个列表、集合、字典等可变的数据类型,在函数内部对它进行操作会怎么样呢??答案是全局变量会跟着改变,至于为什么会产生这种变化,就要从变量的赋值上看了,在此不做过多说明。

函数的参数

函数的参数主要有实参、形参、关键字参数、位置参数、默认参数、非固定参数。
在函数定义的时候,函数名后面的括号里是定义形参、默认参数和非固定参数的,实参和关键字参数则是在函数调用时给函数传递的值。

def test(name,age=22,*args,**kwargs):
	print(name,age,args,kwargs)

test("Tom",sex="M")
  • 形参就是函数定义中的参数,如上述的name,必须传入实参。
  • 默认参数是在函数定义的时候已经给与默认值,如age= 22。
  • 实参,在函数调用的时候,传入的具有实际意义的参数,如“Tom”。
  • 关键字参数,在函数调用的时候,利用赋值语句传入的参数:sex=“M”。
  • 非固定参数,移动有两种,当在定义函数时候不知道这个函数将会输入多少个参数,就可以传入非固定参数,一般用*args,**kwargs表示,前者是一个元祖,输入的如果是单个变量则会添加到args。如果传入的是关键字参数,则会添加到kwargs字典中。注意,再函数内部使用时,不用加星号。

注意:在参数的使用上需要注意,定义函数时,是用形参、默认参数、非固定参数的顺序,传入参数时,关键字参数要在位置参数(按照位置赋值的参数)之后。

函数的类别

嵌套函数
在函数体的内部在定义一个函数,称为嵌套函数。
匿名函数
顾名思义,匿名函数就是没有定义函数名的函数,使用lambda关键字来定义的。最多只能进行简单的三元运算。语法格式如下。

sum_two = lambda x,y:x+y
print(sun_two(2,3))

高阶函数
这也很容易理解,高阶函数就是相当于把一个或多个函数作为参数接收,或者返回一个函数。
递归函数
如果函数在内部在调用自己呢?会发生什么现象?很明显,会无止境地进行调用,系统会报错,但是如果加一个判断条件呢?在满足条件以后就不进行调用了,这就是递归函数。部分算法会使用到。
内置函数
内置函数就是再安装的时候已经定义好了,可以直接使用的函数。不做多讲,自行领悟。

函数的闭包现象

正常情况下函数在运行完之后,该函数在内存中都会被释放。但是如果是这种情况呢?

def ex():
	name = "Tom"
	def inner():
		print("hello,%s" % name)
	return inner
mes = ex()
mes()

此时的mes是inner的内存地址,mes()就相当于调用了inner()的函数,当执行mes()的时候,需要调用ex里、inner外的变量,参数等,这种现象就成为闭包。

列表生成式

这是一个逼格很高的style。可以只使用一行实现多行代码的功能。这用到了匿名函数。

a = [1,2,3,4,5,6,7]
list1 = [i**2 for i in a]

很简单的一行代码就实现了让 列表a里各个元素进行了平方计算。结果生成了一个新的列表。

装饰器

如果对于一个已经实现运行的程序,在不改用调用方式、不改变函数原本代码,怎么实现新增功能呢?我是想破脑袋也没想到,最后揭秘才知道,可以通过装饰器来实现,这是一个很复杂的功能,运用了高阶函数、嵌套函数,还有闭包现象。
在定义外部函数时,需要接受一个函数名func1作为参数,在外部函数执行完毕后,返回内部定义函数名,在内部函数实现一些功能之后会执行func1()。
装饰器的使用是在需要装饰的函数头上利用@装饰器函数名来实现。

生成器(generator)

生成器在我看来相当于一个惰性运算,当把要计算的数和算法传入生成器之后,生成器不要我们来进行下一步运算的指令它才会继续计算,否则就不会计算。
当我们把列表生成式的[]改为()就是一个生成器,当然,只能进行简单的运算。对于生成器的运算可以使用next()让生成器进行下一步运算,也可以使用for循环进行遍历操作。
还有一种就是函数生成器。当对运算比较复杂时,就可以使用函数生成器,在函数内部使用yield关键字,函数就是一个生成器,当函数运行到yield时会停止继续运行下去,跳出函数,直到在外界使用函数生成器时,有两种方法进行下一步运算。

  • next()
  • send()。但是send()使用时要注意需要使用__next__()向生成器传送一个空值,唤醒生成器。然后利用send()向yield后的变量赋值。

作用是可以将函数内部的值在每一次yield的时候返回到外部程序中使用。

迭代器(iterator)

首先说一下可迭代对象,凡是可以用for循环遍历的都是可迭代对象(iterable)。可以使用next()进行下一步运算的是迭代器(iterator),可迭代对象的数据类型可以用iter()来变成迭代器,可以用next()方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值