介绍
函数也可以成为方法,将实现某一功能的代码块封装起来,当你需要实现某一功能时,就可以重用它。
构造
构造一个方法,需要注意:
- 用def定义,关于作用域这方面和循环是一样的:和缩进需要注意。
- 不要忘记(),括号里是参数,参数可无参可有参,用以调用函数时传递数据。
- 在方法体中最后可return 返回任意值,return象征这一个方法的结束,return无参则是返回空值None。
def sumAll():
return 1 # 结束
return a
调用
- 在方法中虽然写好了实现功能的代码,但是如果不调用方法你是永远无法实现其功能的。
- 在方法中的参数为形参,而调用方法的地方传递的参数为实参。两者可为同样的变量名,形参只是为了实现逻辑,实参是为了传实际值。
- 实参与形参互相对应,数量与类型要相符合,如果不符合会报TypeError错误。
# 计算1-...之总和
def sumAll(num): # num为形参
sum = 0
for i in (list(range(num + 1))):
sum += i
print(sum)
num=10
sumAll(num) # 55,num为实参
参数
关于参数我们可以传递任意类型的参数,然而参数也是有可变和不可变的。
一开始介绍py的时候就说到了number、string、tuple是不可变的,list、dict、set是可变的。
不可变参数
以number类型的参数a为例,形参a只是复制实参a的指向,形参a=10,此时形参a指向了10。而实参a还是指向1。
def change(a):
a = 10
a = 1
change(a)
print(a) # 1
魔改代码,完善方法。
def change(a):
a = 10
return a
a = 1
a = change(a)
print(a) # 10
可变参数
以list为例,同样的引用添加元素。
def change(a):
a.append(4) # [1, 2, 3, 4]
a = [1,2,3]
change(a)
print(a) # [1, 2, 3, 4]
默认参数
- 当你的函数中的参数是固定的,比如你要实现一个数的二次方功能,可以设置默认参数。而你调用的时候就可以不用写对应的实参了,如果想改变参数也可以加上去。
- 必选参数要在默认参数前面,如果在默认参数后面又有必选参数,就无法一一对应了。
def cf(num, n=2):
sum = num
while (n > 1):
sum = sum * num
n -= 1
return sum
print(cf(3)) # 9
print(cf(3),3) # 27
- 默认参数必须是不变参数。默认参数从构建方法的时候即构建了,如果是可变参数的话,如代码中的l一直指向的是列表[],当我们调用方法的时候,l指向的列表[]发生改变,再次调用会再次添加,更改的永远是这个列表,这样就失去了了函数的重用性。
def change(l=[]):
l.append('a')
return l
print(change()) # ['a']
print(change()) # ['a', 'a']
如果你不是用默认参数,每次调用方法此时形参与实参指向的是同一个list,所以与上面不同。
def change(l=[]):
l.append('a')
return l
print(change([1, 2, 3])) # [1, 2, 3, 'a']
print(change([1, 2])) # [1, 2, 'a']
关键字参数
- 在参数之前加**,关键字参数允许在方法中传入多个带参数名参数,并会自动组装为dict。
- 必选参数是 一定要传参的,关键字参数与默认参数一样可以不传的,那样的话job是{}。
def init(name, **job):
print("姓名:", name)
print("职业:", job)
init('吉良吉影', 职业1='普通上班族', 职业2='杀手')
# 姓名: 吉良吉影
# 职业: {'职业1': '普通上班族', '职业2': '杀手'}
也可以考虑直接传入字典,但是这样的话要注意你传入的实参字典前面要加**
def init(name, **job):
print("姓名:", name)
print("职业:", job)
job = {'职业1': '普通上班族', '职业2': '杀手'}
init('吉良吉影', **job)
# 姓名: 吉良吉影
# 职业:职业: {'职业1': '普通上班族', '职业2': '杀手'}
命名关键字参数
- 以*为分割符,后面的参数为命名关键字参数。
- 命名关键字参数目的是让传入的形参名称参数相匹配,如果你传入的参数名称不符同样会报TypeError错误。
- 与关键字参数不同,这些参数并不会组成dict,我们只能获取key对应的value了。
def init(name, *, job, city):
print('name:', name)
print(job, city) # 1 2
init('aaa', job='1', city='2')
补充
关键字参数也算是不定长参数,关键字参数是将这些参数组装成字典。
如果参数前面带*可以将参数组装成元组。
def init(name, *job):
print("姓名:", name)
print("职业:", job)
init('空条承太郎', '学生', '卖鱼')
# 姓名: 空条承太郎
# 职业: ('学生', '卖鱼')
参数里的组合
在()里的参数列表顺序应该是怎样的?
参数顺序:(必选参数,默认参数,可变参数,命名关键字参数,关键字参数)
总结
python本身的函数结构还是很简单的,但是在写参数这方面的时候要分很多类型,杀死了我很多脑细胞,实际运用函数不需要这么多类型的参数,用太多也会让他人理解产生障碍。