Python函数、参数及参数解构
函数
- 数学定义:y=f(x),y是x的函数,x是自变量
- Python函数
- 由若干语句块组成的语句块、函数名称、参数列表构成,他是组织代码的最小单元
- 完成一定的功能
- 函数的作用
- 结构化编程对代码的最基本的封装,一般按照功能组织一段代码
- 封装的目的是为了复用,减少冗余代码
- 代码更加简洁美观、可读易懂
- 函数的分类
- 内建函数,如max()、min()
- 库函数,如math.ceil
函数的定义、调用
- def语句定义函数
def 函数名(参数列表): 代码块 #函数体 [return 返回值] 1. 函数名就是标识符,命名要求和标识符命名要求一致 2. 语句块必须缩进,约定四个空格 3. Python的函数没有return语句,隐式会返回一个None值 4. 定义中的参数列表称为形式参数,只使一种符号表达,简称形参
- 调用
- 函数定义,只是声明了一个函数,他不会被执行,需要调用
- 调用的方式,就是函数名加上小括号,括号内写上参数
- 调用时写的参数是实际参数,是传入给函数的值,简称参数
- 函数举例
def add(x,y): result = x + y return result out = add(4,5) print(out)
- 定义需要在调用前,也就是说调用时已经被定义过了,否则报错name is not defined
- 函数是可调用的对象,zaipython中有个内建函数callable() 可以查看标识符是否是一个可调用的对象
- 函数参数
- 参数调用时传入的参数要和定义的参数个数相匹配(可变参数例外)
- 位置参数
- def f(x,y,z) 调用使用f(1,3,5)
- 按照参数定义顺序传入实参
- 关键字参数
- def f(x,y,z) 调用使用f(x=1,y=3,z=5)
- 使用形参的名字来传入实参的方式,如果使用了形参名字,那么传参顺序就可以和定义顺序不同
- 传参
- f(z=None,y=10,x=[1])
- f((1,),z=6,y=4.1)
- f(y=5,z=6,2)
- 要求位置参数必须在关键字参数之前传参,位置参数是按位置对应的
- 函数参数默认值
- 参数默认值
定义时,在形参后跟上一个值 def add(x=4,y=5): return x+y 测试调用: add(6,10)、add(6,y=7)、add(y=7)、add(x=5,6)、add(y=8,4)、add(x=5,y=6)、add(y=5,x=6) 测试 def add(x=4,y)
- 作用
- 参数的默认值可以在未传入足够的实参的时候,对没有给定的参数赋值为默认值
- 参数非常多的时候,并不需要用户每次都输入所有参数,简化函数调用
- 举例:定义一个函数login,参数名host、port、username、password
def login(host='127.0.0.1',port='3306',username='kx',password='7954321'): print('{}:{}@{}/{}'.format(host,port,username,password)) 测试调用 login() login('127.0.0.1',80,'stephon','stephon') login('127.0.0.1',username='root') login('localhost',port=80,password='com') login(port=80,password='7954321',host='www')
- 参数默认值
- 可变参数
- 问题:有多个数需要累加求和
def add(nums): sum = 0 for x in nums: sum += x return sum 测试调用 add([1,3,5])、add((2,5,8)) ==传入迭代元素,迭代元素求和==
- 可变参数:一个形参可以匹配任意个参数
- 位置参数的可变参数
有多个数,需要累加求和 def add(*nums): sum = 0 print(nums) for x in nums: sum += x print(sum) 测试调用add(3,6,9)
- 在形参前使用*标识改形参时可变参数,可以接受多个实参
- 收集多个实参为一个tuple
- 问题:有多个数需要累加求和
- 关键字参数的可变参数
- 关键字参数的可变参数
例子: 配置信息打印 def shouconfig(**kwargs): for k,v in kwargs.items(): print('{}={}'.format(k,v)) 测试调用
- 形参前使用**符号,标识可以接受多个关键字参数
- 收集的实参名称和值组成一个字典
- 关键字参数的可变参数
- 可变参数混合使用
- def showconfig(username,password,**kwargs) - def showcofig(username,*args,**kwargs) - def showconfig(username,password,**kwargs,*args)
- 总结
- 有位置可变参数和关键字可变参数
- 位置可变参数和关键字可变参数都可以收集若干个实参,位置可变参数手机实参形成元组,关键字可变参数收集实参形成一个字典
- 混合使用参数的时候,可变参数要放在参数列表最后,普通参数放在参数列表前面,位置可变参数需要放在关键字参数之前
- keyword-only参数(python3版本中加入)
- 如果一个星号参数后,或者一个位置可变参数后,出现的普通参数,实际上已经不是普通参数了,而是keyword-only参数
def fn(*args,x): print(x) print(args) 测试调用fn(3,5)、fn(3,5,7)、fn(3,5,x=7) args可以看作已经截获了所有的位置参数,x不使用关键字参数就拿不到实参
- 当一个可变关键字参数后面有普通参数时,因为可变关键字参数本省就会收集所有的关键字参数的,这样就失去了意义,所以会直接报语法错误
- keyword-only参数的另一种形式
def fn(*,x,y): print(x,y) 测试调用发现 *号之后,普通形参都变成了必须给出的keyword-only参数
- 可变参数和参数默认值
- 参数列表参数规则:一般顺序是普通参数、缺省参数、可变位置参数、keyword-only参数(可带默认值)、可变关键字参数
- 注意
- 代码应该易读易懂
- 请按照哦书写习惯定义函数参数
参数解构
- 参数解构
- 给函数提供参数的时候,可以在集合类型前使用或者*,把集合类型的结构解开,提取所有的元素作为函数的参数
- 非字典类型使用*解构成位置参数
- 字典类型使用**解构成关键字参数
- 提取出的元素数目要和参数的要求匹配,也要和参数的类型匹配
- 参数解构和可变参数
- 在给函数提供实参的时候,可以在集合类型前使用或者*,把集合类型的结构解开,提取出所有的元素作为函数的实参
def add(*args): result = 0 for x in args: result += x return result 测试调用
练习
- 编写一个函数,能够接受至少两个参数,返回最小值和最大值
In [6]: def fn(*targ): ...: return min(targ),max(targ) In [7]: fn(1,2,4,2,7) #或者可以导入romdom模块,生成列表作为函数参数 Out[7]: (1, 7)
- 编写一个函数,接受一个参数n,n为正整数,打印出如下两种样式,要求数字需要对齐
1
2 1
3 2 1
4 3 2 1
5 4 3 2 1
6 5 4 3 2 1
7 6 5 4 3 2 1
8 7 6 5 4 3 2 1
9 8 7 6 5 4 3 2 1
9 8 7 6 5 4 3 2 1
8 7 6 5 4 3 2 1
7 6 5 4 3 2 1
6 5 4 3 2 1
5 4 3 2 1
4 3 2 1
3 2 1
2 1
1
def fn1(n):
tail = ' '.join([str(i) for i in range(n,0,-1)])
width = len(tail)
for i in range(1,n):
print('{:>{}}'.format(' '.join([str(j) for j in range(i,0,-1)]),width))
print(tail)
----------------------------------------------------------
def f1(n):
for i in range(1,n+1):
print(' '.join([' '*(len(str(n)))]*(n-i)+[' '*(len(str(n))-len(str(j)))+str(j) for j in range(i,0,-1)]))
------------------------------------------------------------------------------
def fnl(n):
for i in range(1,n+1):
for j in range(n,0,-1):
if i < j:
print(' '*len(str(j)),end=' ')
else:
print(j,end=' ')
print()
2.
def fn2(n):
tail = ' '.join([str(i) for i in range(n,0,-1)])
print(tail)
for i in range(len(tail)):
if tail[i] == ' ':
print(' '*i, tail[i+1:])
-------------------------------------------------
def fnl(n):
for i in range(n,0,-1):
for j in range(n,0,-1):
if i < j:
print(' '*len(str(j)),end=' ')
else:
print(j,end=' ')
print()
上下合在一起
def fnl(n):
for i in range(-n,n+1):
if i<0:
for j in range(n,0,-1):
if -i < j:
print(' '*len(str(j)),end=' ')
else:
print(j,end=' ')
print()
elif i == 0:
pass
else:
for j in range(n,0,-1):
if i < j:
print(' '*len(str(j)),end=' ')
else:
print(j,end=' ')
print()
函数返回值
- 返回值总结
- Python函数使用return语句返回‘返回值’
- 所有函数都有返回值,如果没有return语句隐式调用return None
- return语句并不一定是函数的语句块的最后一条语句
- 一个函数可以存在多个return语句,但是只有一条可以被执行。如果没有一条return语句被执行到,就隐式调用return None
- 如果有必要可以显示调用return None,可以简写为return
- 如果函数执行了return语句,函数就会返回,当前被执行的return语句之后的其他语句就不会被执行了
- 作用:结束函数调用,返回值
- 函数不能同时返回多个值
- return [1,2,5] 是指明返回一个列表,是一个列表对象
- return 1,2,5 看似返回多个值,实际上是饮食的被python封装成了一个元组
- 函数嵌套
- 在一个函数中定义了另外一个函数
- 函数有可见范围,这就是作用域的概念
- 内部函数不能被外部直接使用,会报nameerror
本文来自投稿,不代表Linux运维部落立场,如若转载,请注明出处:http://www.178linux.com/87819