函数的非固定参数-Day3

一、函数非固定参数

1、默认函数,我们在传参之前,选给参数指定一个默认的值。默认参数特点是非必须传递的

def test(x,y=2):
    print(x)
    print(y)

print("------没有给默认参数传值------")
test(1)
print("------给默认参数传位置参数------")
test(1,3)
print("------给默认参数传关键字参数------")
test(1,y=3)

#返回值:
------没有给默认参数传值------
1
2
------给默认参数传位置参数------
1
3
------给默认参数传关键字参数------
1
3

 默认参数用途:

  • 安装默认软件(def test(x,soft=True))
  • 传递默认参数值(定义mysql的默认端口号:def count(host.port=3306))

 

二、参数组

之前我们传参数,都是传一个固定参数,不能多也不能少,但是如果说我们需要非固定参数怎么办呢?于是衍生出了,一下以下两种传参方式:

  • *args:非固定位置参数传参,接收N个位置参数,转换成元组的方式
  • **kwargs:非固定关键字传参,接收N个位置参数,转换成字典的方式

 

1、非固定位置参数传参

(1)非固定位置参数可传参类型

def test(*args):        #非固定位置参数传参,形参必须以*开头,args参数名可自定义,args为规范
    print(args)

print("------不传入任何值------")
test()
print("------传入多个位置参数------")
test(1,2,3,4,5)
print("------传入列表------")
test([1,2,3,4,5])
print("------传入列表前加*------")
test(*[1,2,3,4,5])

#返回值
------不传入任何值------
()                                     #什么都不输入,输出空元组
------传入位置参数------
(1, 2, 3, 4, 5)                        #输入多个位置参数,输出元组
------传入列表------ 
([1, 2, 3, 4, 5],)                     #输入列表,输出元组中的一个元素
------传入列表前加*------
(1, 2, 3, 4, 5)                        #输入列表前加*,输入元组

 (2)、位置参数和非固定位置参数混用

def test(x,*args):
    print(x)           #位置参数
    print(args)      #非固定参数

test(1,2,3,4,5)

#返回值
1
(2, 3, 4, 5)

 从上面看出,第一个参数,被当做位置参数,剩下的被当做非固定位置参数

(3)、关键字参数和非固定位置参数混用

def test(x,*args):
    print(x)
    print(args)

test(x=1,2,3,4,5)

#返回值
Traceback (most recent call last):
  File "E:/python/day3/func_test7.py", line 25, in <module>
    test(1,2,3,4,x=5)
TypeError: test() got multiple values for argument 'x'    

 很显然报错,因为x=1是关键字参数,*args是位置参数,而关键字参数不能在位置参数前面,所以报错

 

2、非固定关键字参数传参

(1)非固定关键字参数传参类型

def test(**kwargs):
    print(kwargs)

print("------不传入任何值------")
test()
print("------传入多个关键字参数------")
test(name='wesley', age=24)
print("------传入字典------")
test(**{'name': 'wesley','age': 24})  # 传入字典时,一定要在字典前面加**,否则就会报错

#返回值
------不传入任何值------
{}
------传入多个关键字参数------
{'name': 'wesley', 'age': 24}
------传入字典------
{'name': 'wesley', 'age': 24}

 然而,为什么非固定位置参数不需要加**,非固定关键字参数必须要加**,不加会怎么样呢?

def test(**kwargs):
    print(kwargs)

test({'name':'wesley','age':24})

#返回值:
Traceback (most recent call last):
  File "E:/python/day3/funx_test6.py", line 9, in <module>
    test({'name':'wesley','age':24})
TypeError: test() takes 0 positional arguments but 1 was given

 因为传入的字典被当做位置参数,所以报类型错诶,所以千万要记住:传字典,加**

(2)位置参数和非固定关键字参数混用

def test(name,**kwargs):
    print(name)
    print(kwargs)

print("-------1个位置参数--------")
test("wesley")
print("-------1个位置参数,两个关键字参数--------")
test("wesley",age=24,sex='M')
print("--------3个关键字参数--------")
test(name="wesley",age=24,sex='M')

#返回值
wesley
{}                     
-------1个位置参数,两个关键字参数--------
wesley
{'age': 24, 'sex': 'M'}
--------3个关键字参数--------
wesley
{'age': 24, 'sex': 'M'}

 (3)位置参数、关键字参数和非固定关键字参数混合

def test(name,age=24,**kwargs):
    print(name)
    print(age)
    print(kwargs)          #参数组一定要放在最后

print("-------age默认参数--------")
test("wesley",sex='M',hobby='BMW')
print("-------age位置参数--------")
test("wesley",24,sex='M',hobby='BMW')
print("-------age关键字参数--------")
test(name="wesley",sex='M',hobby='BMW',age=24)    #age关键字参数,放在前后没有影响

#返回值
-------age默认参数--------
wesley
24
{'sex': 'M', 'hobby': 'BMW'}
-------age位置参数--------
wesley
24
{'sex': 'M', 'hobby': 'BMW'}
-------age关键字参数--------
wesley
24
{'sex': 'M', 'hobby': 'BMW'}

 注:如果遇到一个关键字传参和非固定关键字,前后方的位置是不影响传参的,但是我们一般还是按顺序来。

(4)位置参数、关键字参数、非固定位置参数和非固定关键字参数

def test(name,age=24,*args,**kwargs):
    print(name)
    print(age)
    print(args)
    print(kwargs)

print("-------位置参数、非固定位置参数、非固定关键字参数--------")
test("wesley",1,2,3,sex='M',hobby='BMW')
print("-------位置参数、非固定位置参数、非固定关键字参数--------")
test("wesley",24,*[1,2,3],**{'sex':'M','hobby':'BMW'})

#返回值
-------位置参数、关键字参数、非固定位置参数、非固定关键字参数--------
wesley         #name位置参数
1                  #age位置参数
(2, 3)           #非固定位置参数,已转成成元组
{'hobby': 'BMW', 'sex': 'M'}           #非固定关键字参数,已转换成字典
-------位置参数、非固定位置参数、非固定关键字参数--------
wesley 
24  
(1, 2, 3)                #以列表的方式传入,列表前面加*
{'hobby': 'BMW', 'sex': 'M'}          #以字典的方式传入,字典前面加**

 上面的age传参传的是位置参数,那能否传入关键字参数呢?

def test(name,age=24,*args,**kwargs):
    print(name)
    print(age)
    print(args)
    print(kwargs)

test("wesley",age=25,1,2,3,sex='M',hobby='BMW')

#返回值
  File "E:/python/day3/func_test7.py", line 13
    test("wesley",age=25,1,2,3,sex='M',hobby='BMW')
                        ^
SyntaxError: positional argument follows keyword argument   #语法错误,位置参数在关键字参数前面

 看来不可以的,为什么?因为age=19是关键字参数,而后面的*args是非固定位置参数,不管*args传入几个字,它的本质都是位置参数,上面我们提到关键字参数是不能在位置参数前,所以报错了

看来上面的情况不可以的,那能不能非固定关键字参数在非固定位置参数前面呢?

def test(name,age=24,*args,**kwargs):
    print(name)
    print(age)
    print(args)
    print(kwargs)

test("wesley",25,sex='M',hobby='BMW',1,2,3)

#返回值
  File "E:/python/day3/func_test7.py", line 13
    test("wesley",25,sex='M',hobby='BMW',1,2,3)
                                         ^
SyntaxError: positional argument follows keyword argument   #语法错误,关键字参数在位置参数前面

 非固定关键字参数,本质也是关键字参数,是不能放在非固定位置参数的前面

 

三、总结

  • 参数分为:默认参数、位置参数、关键字参数、非固定位置参数、非固定关键字参数
  • 位置参数之前传参,位置不能调换,否则值也会跟着调换;且位置参数多一个或少一个都是不可以的
  • 关键字参数是不能放在位置参数前面的,且不用考虑位置的前面问题
  • 函数传参的位置依次是:位置参数、默认参数(调用位置参数的值)、非固定位置参数、关键字参数、非固定关键字参数

posted @ 2017-12-29 15:51  Wesley·zk  阅读(192)  评论(0)    收藏  举报