Python基础知识梳理-2(函数)

4 函数

在Python中,函数定义的基本形式如下:

def 函数名(函数参数):
	 函数体
	 return 表达式或者值
  • 采用def关键字进行函数的定义,不用指定返回类型
  • 函数参数可以是零个、一个或者多个,函数参数也不需要指定类型
  • 执行到return时代表函数执行完毕,如果没有return会自动返回空值
  • Python允许嵌套定义函数
  • 如果函数返回多个值,会将多个值打包成元组返回。
  • 函数定义前不允许调用该函数

自定义一个求绝对值的my_abs函数为例:

def my_abs(x):
    if x >= 0:
        return x
    else:
        return -x

如果想定义一个什么事也不做的空函数,可以用pass语句:

def nop():
    pass

4.1 函数的参数

形参全称是形式参数,在用def关键字定义函数时函数名后面括号里的变量称为形式参数。

实参全程是实际参数,在调用函数时提供的值或者变量成为实际参数

例:

#这里的a和b就是形参
def add(a,b):
    return a+b
#下面是调用函数
add(1,2)            #这里的1和2就是实参
x = 2
y = 3
add(x,y)            #这里的x和y就是实参

绝大数情况下,在函数内部直接修改形参的值不会影响实参,例:

def addOne(a):
	a +=1
	print(a)    #输出4
a = 3
addOne(a)
print(a)        #输出3

但有些情况下,可以通过特殊的方式在函数内部修改实参的值

def modify1(m,K):
    m = 2
    K = [4,5,6]
    return
def modify2(m,K):
    m = 2
    K[0] = 0                   #同时修改了实参的内容
    return
#主程序
n = 100
L = [1,2,3]
modify1(n,L)
print(n)
print(L)
modify2(n,L)
print(n)
print(L)


'''
100
[1, 2, 3]
100
[0, 2, 3]
'''

如果传递给函数的实参是可变序列,并且在函数内部使用下标或可变序列自身的方法增加、删除元素或修改元素时,实参也会得到相应的修改

def modify(v,item):       #为列表增加元素
     v.append(item)
#主程序
a = [2]
modify(a,3)
print(a)
# [2, 3]

再如修改字典元素值

def modify(d):
    d['age'] = 38
#主程序
a = {'name':'Dong','age':37,'sex':'Male'}
print(a)               # {'name': 'Dong', 'age': 37, 'sex': 'Male'}
modify(a)
print(a)               # {'name': 'Dong', 'age': 38, 'sex': 'Male'}

4.2 函数参数的类型

4.2.1 位置参数

位置参数(positional arguments)是比较常用的形式,调用函数时实参和形参的顺序必须严格一致,并且实参和形参的数量必须相同

例:

def demo(a.b,c):
	print(a,b,c)
demo(1,2,3)                   #按位置传递参数
#1,2,3

demo(1,2,3,4)      #demo() takes 3 positional arguments but 4 were given
                   #实参与形参数量必须相同
4.2.2 默认值参数

默认值参数是指它能够给函数参数提供默认值

def 函数名(……,形参名=默认值):
      函数体
      return 返回值

注意:默认值参数必须在位置参数之后

例:

def power(x,n=2):
	s = 1
	while n>0:
		n = n - 1
		s = s * x
	return s

当我们调用power(5)的时候,相当于调用power(5,2),从上面的例子可以看出,默认参数可以简化函数的调用

设置默认参数时,有几点要注意:

  • 默认参数必须在位置参数之后
  • 设置默认参数可以参考把变化大的参数放前面,变化小的参数可以作为默认参数
  • 默认参数必须指向不变对象

例:

def add_list(L=[]):
	L.append('END')
	return L

上面的代码意思是传入一个list,再添加一个’END’返回,正常调用不会出现问题,但是如果多次调用add_end()就会出现问题

>>> add_end()
['END', 'END']
>>> add_end()
['END', 'END', 'END']

Python函数在定义的时候,默认参数L的值就被计算出来了,即[],因为默认参数L也是一个变量,它指向对象[],每次调用该函数,如果改变了L的内容,则下次调用时,默认参数的内容就变了,不再是函数定义时的[]了。

定义默认参数要牢记一点:默认参数必须指向不变对象!

要修改上面的例子,我们可以用None这个不变对象来实现:

def add_end(L=None):
    if L is None:
        L = []
    L.append('END')
    return L

为什么要设计strNone这样的不变对象呢?因为不变对象一旦创建,对象内部的数据就不能修改,这样就减少了由于修改数据导致的错误。

4.2.3 关键字参数

关键字参数是通过参数名字匹配的,不需要严格按照参数定义时的位置来传递参数。

例:

def display(a,b):
	print(a)
	print(b)
    
#下面两句达到的效果是相同的
display(a = 'word',b = 'hello')
display(b = 'hello',a = "world")


'''
word
hello
world
hello
'''
4.2.4 可变参数

可变参数就是传入的参数个数是可变的,可以是1个、2个到任意个,还可以是0个。

例:一个人可以有多个昵称,此时无法确定参数的个数,只需要在参数前面加上*或者**

def storename(name,*nickName):
    print('real name is %s'%name)
    for nickname in nickName:
    	print("昵称",nickname)

#主程序
storename('张三')
storename('张三','小张')
storename('张三','zhangsan')

'''
real name is 张三
real name is 张三
昵称 小张
real name is 张三
昵称 zhangsan
'''

***表示能够接受0到任意多个参数

  • *表示将没有匹配的值都放到同一个元组中
  • **表示将没有匹配的值都放到一个字典中

假如使用**

def demo(**p):
	for item in p.items():
		print(item)
demo(x=1,y=2,z=3)

'''
('x', 1)
('y', 2)
('z', 3)
'''

假如使用*

def demo(*p):
	for item in p:
		print(item,end=' ')
demo(1,2,3)

#1 2 3 

4.3 变量的作用域

1 局部变量

在函数内定义的变量只在该函数内起作用,称为局部变量。变量起作用的范围称为变量的作用域。

例:

def fun():
	x = 3
	count = 2
	while count > 2:
		print(x)
		count = count - 1
fun()
print(x)               # name 'x' is not defined   
2 全局变量

全局变量在函数外定义,作用域是整个程序。全局变量可以直接在函数里面使用,如果要在函数内改变全局变量值,必须使用global关键字进行声明。

x = 2                            #全局变量
def fun1():
	print(x,end=" ")
def fun2():
	global x                     #在函数内部改变全局变量值必须使用global关键字
	x = x + 1
	print(x,end=" ")
fun1()
fun2()
print(x,end=" ")

#2 3 3 

4.4 函数参数序列解包

传递参数时,可以通过在实参序列前加一个*将其解包,然后传递给多个单变量形参。

def demo(a, b, c):
   return a+b+c

seq = [1, 2, 3]
print(demo(*seq))
#6

tup = (1, 2, 3)
print(demo(*tup))
#6

>>> Set = {1, 2, 3}
>>> print(demo(*Set))
#6

>>> dic = {1:'a', 2:'b', 3:'c'}
>>> print(demo(*dic))
#6
>>> print(demo(*dic.values()))
#abc
>>> print(demo(*dic.keys()))
#6

如果函数实参是字典,可以在前面加**进行解包,等价于关键参数。

>>> def demo(a, b, c):
    	     return a+b+c

>>> dic = {'a':1, 'b':2, 'c':3}
>>> print(demo(**dic))
#6
>>> print(demo(a=1, b=2, c=3))
#6
>>> print(demo(*dic.values()))
#6

4.5 闭包和递归

闭包指函数的嵌套。可以在函数内部定义一个嵌套函数,将嵌套函数视为一个对象

例:

def func_lib():
	def add(x,y):
		return x+y
	return add       #返回函数对象
fadd = func_lib()
print(fadd(1,2))
#3

函数在执行的过程中直接或间接的调用自己本身,称为递归调用。

例:求1~5的平方和

def f(x):
	if x==1:
		return x
	else:
		return(f(x-1)+x*x)  #调用f()函数本身
print(f(5))

# 55

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值