函数
一、函数定义以及调用
定义函数:
def 函数名([参数...]):
逻辑操作~~
调用:
函数名([参数…])
demo:
需要特别注意python的命名规范,和java的驼峰式命名不同,方法名尽量分段小写。规则和c基本一样。
带返回值的函数:
def add(num1,num2)
return num1+num2
形参和实参:
def myFirstFunction(name)
函数部分相关属性和参数:
①查看函数文档:
函数名.__doc__
②用help也可以
函数参数分类
①位置参数
调用函数时根据函数定义的参数位置来传递参数,
两个参数的顺序必须一一对应,且少一个参数都不可以
ex:
def power(m,n):
result=1
while n>0:
n=n-1
result=result*m
return result
调用:print(power(4,3))
② 默认参数
定义了默认值的参数,最大的好处就是降低调用函数的难度:
def myFunction(name=‘秦时明月’,words=‘玄机科技’):
print(name+’->’+words)
需要注意的是:
1.必须参数在前,默认参数在后
2.默认参数一定要指向不变对象!
③ 可变参数【也叫任意参数】
等同于java中的 Object…
你可以传入任意多个元素(包括0)到参数中,在函数内部会自动认为是一个元组或列表,用*
号来表示。
特征:args
def cartoonList(*args):
for n in args:
print(args)
④ 关键字参数
在函数调用的时候,通过参数名指定需要赋值的参数,这样就可以放置参数传入的位置不对,导致诸多问题 。
在python中关键字参数习惯用**kw表示,可以传入0到任意多个“key-value”键值对
,参数在函数内部被当做一个字典结构,ex:
def testArg(**kw)
def testArg(city,**kw)
调用的话:
testArg(name='John',job='programmer')
testArg('beijing',name='zzg')
demo:
函数的返回值
python中因为变量只有名字,没有类型,所以其函数返回值也是没有类型的,
换言之,python中的函数关于返回值方面,真的是可以为所欲为的。
局部变量与全局变量
其他都还好,有两点和java不同,
①如果在函数内部有和全局函数一样的变量名,那么值就取局部变量的,正常,没啥不同,问题是如果在函数内部调用全局变量,然后接着定义跟全局变量名字一样的局部变量,那么,红色wait for you,一般也不要犯这种错误,代码规范真的挺重要的!
②可以先使用再定义,js es6之前也可以,es6就废除了,容易出bug,所以我觉得python以后应该也会取消这一个操作,而且这样也确实跟习惯不一样,所以还是先定义在使用吧。
cartoonName='天行九歌'
def cartoonArg(name,*arg):
print('CartoonName:'+name)
for item in arg:
print(item)
print('Global variable:'+cartoonName)
cartoonArg('空山鸟语','焰灵姬','韩非子','赵某人')
print('Origin:'+cartoonName)
输出结果:
CartoonName:空山鸟语
焰灵姬
韩非子
赵某人
Global variable:天行九歌
Origin:天行九歌
内嵌函数和闭包
首先,先来个新姿势:如果想把局部变量变成全局变量,只需要在变量前加一个global关键字即可【这个操作?还好方向盘还在,就是车没了】
def myTest2():
global myArg
myArg='漠北'
print(myArg)
言归正传,内嵌函数,也叫内置函数,就是函数内部再嵌套一个函数呗:
def zFunction1():
print('正常函数...Zzg')
def zFunction2():
print('内嵌函数...Zzg')
zFunction2()
调用:
zFunction1()
输出结果:
正常函数...Zzg
内嵌函数...Zzg
Tips:
内嵌函数的作用域在整个外部函数的内部,只能在外部函数内调用这个函数。另外再强调一下IDLE的Alt+P快捷键,相当于Ctlr+V最近的输出。
闭包:闭包是由函数及其相关的引用环境组合而成的实体(即:闭包=函数+引用环境)(想想Erlang的外层函数传入一个参数a, 内层函数依旧传入一个参数b, 内层函数使用a和b, 最后返回内层函数),ex:
def FunX(a):
def FunY(b):
return a*b
return FunY
查看类型*
i=FunX(5)#先赋值
type(i)#查看类型
,结果如下:
<class 'function'>
可见类型就是函数~,传参就有两种方式了:
i(6)-->30
FunX(5)(6)-->30
Tips:关于闭包常犯的错误:
①在外部函数中定义变量,然后在内嵌函数中使用,ex:
def Fun1():
x=5
def Fun2():
x*=5
return x
return Fun2()
这时候在调用Fun1()就会出错,因为return Fun2()的时候会直接走进Fun2()里面,里面是没有定义x的,就会报错:
UnboundLocalError: local variable 'x' referenced before assignment
解决方案有两种:
①采用容器类型参数(也就是list、tuple)
def Fun3():
x=[5]
def Fun4():
x[0]*=x[0]
return x
return Fun4()
②nonlocal关键字
def Fun3():
x=5
def Fun4():
nonlocal x
x*=x
return x
return Fun4()
Lambda表达式:
①lambda 入参 :函数体
②当有多个入参的时候用逗号隔开即可,ex:
lambda x,y,z…: 表达式
1.只有一个参数
g=lambda x:x*x
g(3)
-->9
2.有两个参数
g=lambda x,y : x+y
g(3,4)
-->7
lambda表达式的优势:
①python写一些执行脚本的时候,使用lambda就可以省下来定义函数的过程,写简单脚本使用,怎么说呢,相当于一个比较小的函数吧
②对于一些比较抽象并且整个程序执行下来就需要调用一两次的函数,用lambda还是不错的,省的起名字了嘛
③简化代码,增强可读性
暂且这么多,接下来介绍两个比较重要的函数:
1.filter()
| filter(function or None, iterable) --> filter object
看定义:两个参数,前面可为空或者为过滤函数,如果第一个参数为None,那么就把后面变量里为True的值筛选出来,后面就是可迭代变量喽,为None的就不写了,看第二种函数应该根据变量值,决定return 1还是0(True或False):
获取可迭代对象里所有的奇数:
def odd(x):
return x % 2
temp=range(10)#生成0~9,10个数字
list(filter(odd,temp))
-->[1,3,5,7,9]
可见函数不需要再加(),只需要传入函数名即可。
将这个转成lambda表达式就是:
list(filter(lambda x: x % 2,range(10)))
2.map():
map(func, *iterables) --> map object
两个参数,第一个为function,第二个是可迭代变量;
作用就是把可迭代对象的每一个值都作为参数传入到第一个变量函数中去,最后可迭代结果,ex:
list(map(lambda x : x*2,range(10)))
-->[0,2,4,6,8,10,12,14,16,18]
Lambda
lambda函数可接受任意数量的参数,但只能有一个表达式。
语法:
lambda arguments:expression
demo:
这个少不了用,但是当下对这个使用场景还不清楚。待后续完善场景。
递归
就是函数调用自身,有点编程基础的都懂啦。写个Python阶乘的吧,毕竟还没用python实现过递归呢。
def jieCheng(i):
if i==1:
return 1
else:
return i*jieCheng(i-1)
---》jieCheng(5)-->120