python 函数
定义
函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需调用其函数名即可。
特性
- 减少代码重复
- 使程序变得可扩展
- 使程序变得易于维护
函数的创建
python中创建函数,需要使用__def__关键字,后面写函数的名字,然后是形参列表,大体如下:
def 函数名(形参列表):
函数体......
return 返回值
其中形参列表和 return返回值并不是必须的。
函数的使用
想要调用函数程序,需要以函数名加括号的形式进行调用,而括号内可以传入参数,而括号内的参数我们称之为__实参列表__,传入的实参会通过形参传递进函数,在函数内部就可以使用了。如下:
def add(x,y):
return x + y
# 调用函数
add(10,20)
需要注意的是,python中的实参列表每一个参数之前用逗号分割,而向add()括号内的10,20这样的参数我们称之为位置参数(positional argument)。
那么需要注意的是,在python中,函数的实参的个数必须和形参的个数一样,实参个数多于形参或者少于形参都会报错。
函数的参数
形参也可以叫做形参变量,只有在被调用时才分配内存单元,在调用结束时,即释放所分配的内存单元。所以形参只能在函数内部生效。函数调用结束返回主调用函数后则不能够再使用该形参变量。
实参可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。因此应预先用赋值,输入等办法使参数获得确定值
默认参数
首先,先来看下面的代码:
def stu_register(name,age,country,course):
print('------注册学生信息--------')
print('学员姓名:',name)
print('学员年龄:',age)
print('学员国籍:',country)
print('学员选择课程:',course)
stu_register('小明',19,'中国','web前端')
stu_register('小红',20,'中国','linux')
stu_register('李白',25,'中国','python')
在上面的实例中,每一个学员注册的国籍都是中国,而在网上的一些网站中,如果不去手动设置,都默认为中国,这就是通过默认参数实现的。
如下,把country变成默认参数,
def stu_register(name,age,course,country='中国')
那么此时再注册学员的时候如果国籍是中国就可以不需要进行国籍的传参,而是采用默认的参数。
关键参数
正常情况下,给函数传参数要按顺序,不想按顺序就可以用关键参数,只需指定参数名即可,但记住一个要求就是,关键参数必须放在位置参数之后。
# 使用关键字参数
stu_register(name='小明',country='中国',age=19,course='linux')
'''关键字参数必须放在位置参数之后'''
stu_register('小红',country='中国',age=19,course='linux')
非固定参数
如果你的函数中并不是很确定用户会传入多少个参数,那么就可以使用非固定参数。
'''非固定参数'''
def test01(x,y,*args):
print(x,y)
print(args)
test01('李白','艳艳',12,3,4)
输出结果为:
李白 艳艳
(12, 3, 4)
需要注意的是,当使用了*args的时候,会发现传入的参数全部被放在了一个元组中。那么如果想要操作的话只需按照元组的操作方式操作即可。
非固定参数除了可以转换成元组以外,还可以将传入的数据转换成字典,需要使用**kwargs,代码如下:
def stu_register(name,age,*args,**kwargs): # *kwargs 会把多传入的参数变成一个dict形式
print(name,age,args,kwargs)
stu_register("Alex",22)
#输出
#Alex 22 () {}#后面这个{}就是kwargs,只是因为没传值,所以为空
stu_register("Jack",32,"CN","Python",sex="Male",province="ShanDong")
#输出
# Jack 32 ('CN', 'Python') {'province': 'ShanDong', 'sex': 'Male'}
局部变量和全局变量
在python中,函数外部声明的变量我们称之为全局变量,在函数内部声明的变量是局部变量。
全局变量可以在变量声明之后的任何位置使用,而局部变量只能够在函数内部使用。
'''全局变量和局部变量'''
name = '李白' # 函数外部声明 ,称之为全局变量
def test():
age = 20 # 函数内部声明,称之为局部变量
print(age) # 局部变量只能够在函数内部使用
print(name) # 全局变量可以在函数内部使用
test()
# print(age) 在函数外部没有办法使用局部变量
如果想要在函数内部声明全局变量,需要使用global关键字
def test():
global test
test = '李白斗酒诗百篇'
test()
print(test) # 李白斗酒诗百篇
通过global关键字就能够在函数内部创建全局变量,但是这种写法是不推荐使用的,有可能造成变量污染。
还有一点需要注意,看下面的代码:
name = '艳艳'
def test():
# 在函数中更改全局变量name的值
name = 'hello,world'
print(name) # hello,world
test()
print(name) # 艳艳
上述代码中,在函数中对全局变量进行了更改,并且打印更改之后的变量,那么打印的结果是更改的结果,但是在函数的外面再次打印在函数中更改的全局变量,发现结果并没有被更改,因为在函数中更改全局变量,那么更改过后的值作用域仅停留在函数当中。
那么如何在函数中对全局变量更改并且在函数外部调用结果为更改之后的值呢?同样可以使用global关键字来实现。
name = '艳艳'
def test():
global name
# 在函数中更改全局变量name的值
name = 'hello,world'
print(name) # hello,world
test()
print(name) # hello,world
返回值
要想获取函数的执行结果,就可以用return语句把结果返回
注意:
函数在执行过程中只要遇到return语句,就会停止执行并返回结果,so 也可以理解为 return 语句代表着函数的结束
如果未在函数中指定return,那这个函数的返回值为None 。
递归函数
在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。
'''创建一个递归,将传入的参数不断的除以2,到0为止'''
def calc(n):
print(n)
if int(n/2) > 0 :
return calc( int(n/2) )
calc(10)
输出结果为:
10
5
2
1
递归特性:
-
必须有一个明确的结束条件
-
每次进入更深一层递归时,问题规模相比上次递归都应有所减少
-
递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)
堆栈扫盲http://www.cnblogs.com/lln7777/archive/2012/03/14/2396164.html