php发展

注册

 

发新话题 回复该主题

Python其实很简单第十二章函数与变量 [复制链接]

1#

在前面已经多次提到函数这个概念,之所以没有解释什么是函数,是因为程序中的函数和数学中的函数差不多,如input()、range()等都是函数,这些都是Python的标准函数,直接使用就可以了。根据需要,用户也可以自定义函数。

12.1函数

1、函数的结构:

def函数名(参数):

函数体

return返回值

例如:数学中的函数f(x)=2x+5在Python中可以定义如下:

deff(x)/p>

y=2*x+5

return(y)

如果x取值为3,可以使用如下语句调用函数:

f(3)

下面给出完整的程序代码:

deff(x)/p>

y=2*x+5

return(y)

res=f(3)

print(res)

运行结果:11

如上例中的x是函数f(x)的参数,有时也被称为形式参数(简称形参),在函数被调用时,x被具体的值3替换y就是函数的返回值,这个值3也被称为实际参数(简称实参)。

上例中的y是函数f(x)的返回值。并不是所有的函数都有参数和返回值。如下面的函数:

deffunc()/p>

print(此为无参数传递、无返回值的函数)

func()

输出结果:此为无参数传递、无返回值的函数

可以看出,该函数func()无参数,故调用时不用赋给参数值。

函数也可以有多个参数,如f(x,y)=x+y,可用Python语言定义如下:

deff(x,y)/p>

z=x**2+y**2

returnz

print(f(2,3))#调用函数f(x,y)

输出结果:13

2、也可以通过直接给参数列表中的参数赋值的方法,为参数添加默认值,如果用户赋予参数值,则按照用户赋值执行,否则使用默认值。例如:

deff(x,y=3)/p>

z=x**2+y**2

returnz

若调用时参数列表为(2,1),即x赋值为2,y赋值为1:

print(f(2,1))

输出结果为:5

若调用时参数列表为(2),即x赋值为2,y赋值省缺,则y使用默认值:

print(f(2))

输出结果为:13

3、回调函数,又称函数回调,是将函数作为另一函数的参数。

例如:

deffunc(fun,m,n):

fun(m,n)

deff_add(m,n):

print(m+n=,m+n)

deff_mult(m,n):

print(m*n=,m*n)

func(f_add,2,3)

func(f_mult,2,3)

输出结果:

m+n=5

m*n=6

在f_add(m,n)和f_mult(m,n)被定义前,func(fun,m,n)中的fun(m,n)就已经调用了这两个函数,即“先调用后定义”,这也是回调函数的特点。

4、如果无法预知参数的个数,可以在参数前面加上*号,这种参数实际上对应元组类型。譬如,参会的人数事先不能确定,只能根据与会人员名单输入:

deffunc(*names):

print(今天与会人员有:)

fornameinnames:

print(name)

func(张小兵,陈晓梅,李大海,王长江)

运行后,输出结果为:

今天与会人员有:

张小兵

陈晓梅

李大海

王长江

5、参数为字典类型,需要在参数前面加上**号。

deffunc(**kwargs):

foriinkwargs:

print(i,kwargs)

func(a=a1,b=b1,c=c1)

输出结果为:

aa1

bb1

cc1

6、一个有趣的实例:

deffunc(x,y,z,*args,**kwargs):

print(x,y,z)

print(args)

print(kwargs)

func(a,b,c,Python,iseasy,py=python,j=java,ph=php)

输出结果:

abc#前三个实参赋给前三个形参

(Python,iseasy)#*args接收元组数据

{py:python,j:java,ph:php}#**kwargs接收字典数据

12.2变量的作用域

变量的作用域即变量的有效范围,可分为全局变量和局部变量。

1、局部变量

在函数中定义的变量就是局部变量,局部变量的作用域仅限于函数内部使用。

2、全局变量

在主程序中定义的变量就是全局变量,但在函数中用关键字global修饰的变量也可以当做全局变量来使用。

全局变量的作用域是整个程序,也就是说,全局变量可以在整个程序中可以访问。

下面通过实例去讨论:

程序1:

a=1#a为全局变量

defa_add():

print(a的初值:,a)#在函数中读取a的值

a_add()#调用函数a_add()

a+=1#主程序语句,a增加1

print(a现在的值是:,a)#主程序语句,读取a的值

运行结果:

a的初值:1

a现在的值是:2

这个结果和我们想象的一样,全局变量a既可以在主程序中读取,也可以在子程序(函数)中读取。

程序2:

a=1

defa_add():

a+=1

print(a的初值:,a)

a_add()

print(a现在的值是:,a)

运行程序1时出现如下错误提示:

UnboundLocalError:localvariableareferencedbeforeassignment

意思是:局部变量a在赋值之前被引用。

从语法上来讲,该程序没有错误。首先定义了一个全局变量a并赋值为1,又定义了一个函数a_add(),函数内的语句a+=1就是出错的根源,虽然我们的初衷是想让全局变量a的值增加1,但从错误提示看,这个语句中的a并不是全局变量,而是局部变量。看来,在函数中读取全局变量的值是没有问题的(在程序1中已经得到了验证),但要在函数中改变全局变量的值是不行的(在程序2的错误提示a+=1中的a是局部变量,而非全局变量)。

怎样解决这个问题?

程序3:

a=1

defa_add(x):

x+=1

returnx

print(a的初值:,a)

a=a_add(a)

print(a现在的值是:,a)

运行结果:

a的初值:1

a现在的值是:2

结果的确是正确的,但在函数a_add(x)中没有调用变量a(没有出现变量a)。

程序4:

a=1

defa_add(a):

a+=1

returna

print(a的初值:,a)

a=a_add(a)

print(a现在的值是:,a)

运行结果:

a的初值:1

a现在的值是:2

对比程序4和程序3不难发现,其实程序4只是简单的把函数的参数x变成了a,这个a的实质和程序3中的x还是一样的。这进一步证实,函数中的a是局部变量,与主程序的全局变量a有着本质的区别。

程序5:

a=1

defa_add():

globala

a+=1

print(a的初值:,a)

a_add()

print(a现在的值是:,a)

运行结果:

a的初值:1

a现在的值是:2

程序5和程序2相比较,仅仅是在函数中添加了一个定义“globala”,此时的局部变量a就可以当做全局变量使用,由于它和全局变量a同名,自然也就不用区分a究竟是全局变量还是局部变量了,在主程序和该函数内都可以访问、修改变量a的值了。

虽然使用global可使变量使用起来非常方便,但也容易引起混淆,故在使用过程中还是谨慎为好。

12.3函数的递归与嵌套

1、递归,就是函数调用它自身。递归必须设置停止条件,否则函数将无法终止,形成死循环。

以计算阶乘为例:

deffunc(n):

ifn==1:

return1

else:

returnn*func(n-1)#func()调用func()

print(func(5))

运行结果为:

2、嵌套,指在函数中调用另外的函数。这是程序中常见的一种结构,在此不再赘述。

3、匿名函数

Python中可以在参数前加上关键字lambda定义一个匿名函数,这样的函数一般都属于“一次性”的。

例如:

程序1:这是一个常规的函数定义和调用。

deff_add(x,y):

returnx+y

print(f_add(2,3))

输出结果:5

程序2:使用lambda定义匿名函数。

f_add=lambdax,y+y

print(f_add(2,3))

输出结果:5

从上面的代码可以看出,使用lambda仅仅减少了一行代码。f_add=lambdax,y+y中的f_add不是变量名,而是函数名。程序1和程序2的print()语句中的参数都是一样的——调用函数f_add()。所以,匿名函数并没有太多的优点。

本文由大漠孤驼原创,匠心之作,纯粹干货,欢迎

分享 转发
TOP
发新话题 回复该主题