详解Python函数参数定义及传参(必备参数、关键字参数、默认可省略参数、
可变不定长参数、。。。
详解Python函数参数定义及传参(必备参数、关键字参数、默认可省略参数、可变不定长参数、*args、**kwargs)
Python函数参数传参的种类
  Python中函数参数定义及调⽤函数时传参⼤体可分必备参数、关键字参数、默认可省略参数、不定长元组参数、不定长关键字参数等,下⾯通过函数定义及调⽤上的不同情况深⼊解析这些中参数的不同及应⽤场景。
  为了更好的理解不同参数的具体意义,所以下⾯演⽰代码中,使⽤的参数数量较多。具体是⼀个调⽤MySQL数据库配置参数的函数所需要的参数,我们⽤这个来演⽰不同类型的特点及适⽤⽅法,了解每种类型的应⽤场景及优缺点。
必备参数__仅赋值传参
  必备参数,就是在调⽤函数的时候,定义的参数要全部都有赋值,否则执⾏的时候代码会报错。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 演⽰获得数据库配置参数,使⽤必备参数
def demo_get_conf1(user, pw, host, port, db, charset):
"打印得到的数据库配置"
print('host: ', host)
print('port: ', port)
print('user: ', user)
print('pw: ', pw)
print('db: ', db)
print('charset: ', charset)
demo_get_conf1('root','1234','127.0.0.1','3306','tests','utf8')
  上述代码中,调⽤demo_get_conf1函数的时候,定义的所有参数都必须传递,并且要按照规定的顺序传递,否则函数体内得到的也是错误的。以上代码控制台输出:
host:  127.0.0.1
port:  3306
user:  root
pw:  1234
db:  tests
charset:  utf8
  这也是我们希望得到的正确结果。
  下⾯我们把上述代码最后⼀⾏调⽤的前两个参数(“root"和"1234”)对调⼀下:
demo_get_conf1('1234','root','127.0.0.1','3306','tests','utf8')
  执⾏后控制台输出:
host:  127.0.0.1
port:  3306
user:  1234
pw:  root
db:  tests
charset:  utf8
  很显然,得到的 user 变成了 1234,pw 变成了 root,也就是说是完全按照位置来对应函数定义时的参数变量,所以传参的时候,顺序不能错,参数⽐较多的时候,就不容易记住顺序了。那么Python还给⼤家⼀种传递⽅式,同样是上⾯的函数,可以不⽤按顺序传参,请看下节“必备参数__键值对传参”。
必备参数__键值对传参(关键字参数)
  同样是必备参数,但是在代⽤函数传参的时候,可以直接使⽤键值对的⽅式,看下⾯演⽰代码:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 演⽰获得数据库配置参数,使⽤必备参数
def demo_get_conf1(user, pw, host, port, db, charset):
"打印得到的数据库配置"
print('host: ', host)
print('port: ', port)
print('user: ', user)
print('pw: ', pw)
print('db: ', db)
print('charset: ', charset)
demo_get_conf1(
charset='utf8',
pw='1234',
user='root',
host='127.0.0.1',
port='3306',
db='tests')
  控制台输出:
host:  127.0.0.1
port:  3306
user:  root
pw:  1234
db:  tests
charset:  utf8
  函数定义还是与上例⼀样,只是调⽤函数的时候,参数传递使⽤了键值对,键名就是参数定义时的变量名,这样就可以不⽤理会顺序,只要记住键名(参数变量名)就可以了。
  但是这毕竟是必备参数,所有的参数都要传递,否则会报错,例如将调⽤修改成:
demo_get_conf1(
pw='1234',
user='root',
host='127.0.0.1',
port='3306',
db='tests')
  控制台会输出:
TypeError: demo_get_conf1() missing 1 required positional argument: 'charset'
  提⽰缺少’charset’参数,代码不能正常运⾏。那么有没有可以缺省参数,⽤就传递,不⽤就不传递的,Python肯定也有这种参数,继续看下⼀节“默认可省略参数”。
默认可省略参数
  默认可省略参数,就是在定义的时候就给了默认值,如果在函数调⽤的时候给这个参数传值了,那么就使⽤传递的值,如果没有传递就使⽤定义时候的默认值。
def demo_get_conf2(user, pw, host, port, db, charset='utf8'):
"打印得到的数据库配置"
print('host: ', host)
print('port: ', port)
print('user: ', user)
print('pw: ', pw)
print('db: ', db)
print('charset: ', charset)
demo_get_conf2('root','1234','127.0.0.1','3306','tests')
  在上述代码中,调⽤demo_get_conf2函数的时候,我们并没有传递第六个参数charset,但是代码没有报错,控制台输出:
host:  127.0.0.1
port:  3306
user:  root
pw:  1234
db:  tests
charset:  utf8
  可见参数"charset"虽然在调⽤的时候没有传递,但是依然得到了值"utf8",这个值就是在函数定义时候,参数"charset"赋值的默认值。
  但是这个参数必须在后⾯,否则调⽤的时候按照顺序赋值的时候,少传递⼀个就不是这个有默认值的了,所以Python不允许那样做,看下⾯的例⼦:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 演⽰获得数据库配置参数,使⽤默认可省略参数
def demo_get_conf1(user, pw, host, port, db='tests', charset):
"打印得到的数据库配置"
print('host: ', host)
print('port: ', port)
print('user: ', user)
print('pw: ', pw)
print('db: ', db)
print('charset: ', charset)
demo_get_conf1('root','1234','127.0.0.1','3306','tests')
  控制台输出:
SyntaxError: non-default argument follows default argument
  提⽰⾮默认参数不能在默认参数之后,代码不能正常执⾏。
  有些时候,我们不能确定要具体传递⼏个参数,应⽤场景需要的参数数量差异较⼤,那么是否可以动态传递不同数量的参数呢,继续看下⼀节“可变长元组参数”
不定长元组参数(*args)
  不定长元组参数,就是不确定数量的参数,定义⼀个参数把传⼊的参数组合成元组,来接收函数调⽤时传递过来的N个参数,在函数体内以元组形式按顺序读取。为了演⽰更多是使⽤场景,下⾯没有使⽤⽹络中通常使⽤的循环⽅式来取可变长元组参数。
def demo_get_conf3(host, port,*cnf):
"打印得到的数据库配置"
print('host: ', host)
print('port: ', port)
print('user: ', cnf[0])
print('pw: ', cnf[1])
print('db: ', cnf[2])
print('charset: ', cnf[3])
demo_get_conf3('127.0.0.1','3306','root','1234','tests','utf8')
控制台输出:
host:  127.0.0.1
port:  3306
user:  root
pw:  1234
db:  tests
charset:  utf8
  可见这是我们正常需要得到的结果,可以多传更多的参数,只要⾥⾯取值的数量没有超过传递过来可变参数的数量,就不会报错。
  在上例中,host 和 port 是必备参数,函数调⽤的时候,在这两个参数后⾯所传递的,就都是对应到函数定义时的变长参数元组⾥了。  在Python中,函数参数是可以使⽤元组的,那么这总定义与直接使⽤元组参数有什么区别呢,下⾯看使⽤元组参数的⽰例:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 演⽰获得数据库配置参数,使⽤元组参数
def demo_get_conf4(host, port, cnf):
"打印得到的数据库配置"
print('host: ', host)
print('port: ', port)
print('user: ', cnf[0])
print('pw: ', cnf[1])
print('db: ', cnf[2])
print('charset: ', cnf[3])
demo_get_conf4('127.0.0.1','3306',('root','1234','tests','utf8'))
  控制台输出:
host:  127.0.0.1
port:  3306
user:  root
pw:  1234
db:  tests
charset:  utf8
  与上⼀例⽐,函数体⼀模⼀样,参数 cnf 只是少了个 “*”。重点是调⽤的时候不同,可以看出明显的区别,可变长元组参数在调⽤的时候,可以与必备参数⼀样依次传递,⽽定义元组类型参数,调⽤函数传递参数时,需要传递元组类型的数据才可以。
python新手函数  这种参数传递的时候,元组⾥⾯的元素也是要强调顺序的,如果是累加⼀类的函数,顺序不重要,如
果是每个元素都代表不同具体含义的,那顺序就⼗分重要,不可以搞错,否则与必备参数⼀样,会在函数体内取值错误。
  在上两例中,只能算是元组参数,还不能算不定长,因为函数体内的取值规定了元组的元素数量,那接下来看⼀个⽹络上通常写法的例⼦:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 演⽰获得数据库配置参数,使⽤可变长元组参数
def demo_get_conf5(x, y,*nums):
"得到累加和"
res = x + y
for i in nums:
res += i
return res
print(demo_get_conf5(10,20,))
print(demo_get_conf5(10,20,15,25,30))
print(demo_get_conf5(10,20,15,25,30,50,30))
  控制台输出:
30
100
180
  上例中,前两个参数是必须传的,后⾯的参数可传可不传,传的数量也不固定,根据需要由外部调⽤决定,所以这是可变长参数。但是这种应⽤适合元组内参数是相同类型和作⽤,如果回到上⾯的配置参数应⽤中,是否可以不定长的呢,看下⾯的代码:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。