函数的参数类型有很多,比如说:位置参数、默认值参数、关键参数、命名关键参数、可变长度参数

(1)>>> 函数名              查看函数的内存地址

(2)>>>dir(函数名)         查看函数的属性

 

一、位置参数(positional arguments),调用时实参和形参的顺序必须严格一致,并且实参和形参的数量必须相同。

#定义
def power(x,n):
    s = 1
    while n > 0:
        n -= 1
        s *= x
    return s
#调用
power(5)#错误
power(4,5)#正确

 

二、默认值参数

#在上面的代码中,我们计算的是x的n次方,如果我们经常计算x的平方,我们可以用默认值参数,注意默认值参数只能出现在函数参数的最后
def power(n=2,x):#错误的
    pass

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

#调用
power(5)#正确,计算5的平方
power(5,3)#这也是正确的,计算的是n>2的情况

#注意,如果默认值参数使用不当会导致很难发现的逻辑错误
#例如
def demo(newlist,old_list=[]):
    old_list.appen(newlist)
    return old_list
print(demo('5',[1,2,3,4]))#[1,2,3,4,5]
print(demo('aaa',['a','b']))#['a','b','aaa']
print(demo('a'))#['a']
print(demo('b'))#['a','b'],这是因为上一个语句中只传入了一个参数即newlist,所以返回的old_list = ['a'],当再次调用时,虽然只传入了一个参数,但是此时old_list已经被定义了

#要解决这个问题,谨记:默认参数必须指向不变的变量
def demo(newlist,old_list=None):#None不变对象作为默认参数
    pass

#注意
#(1)默认值参数只在函数定义时被解释一次
#(2)可以使用“函数名.__defaults__”查看所有默认参数的当前值
#例如
demo.__defaults__


#首先有个学生注册的函数,需要传入name和gender两个参数
def enroll(name,gender):
    print('name:',name)
    print('gender:',gender)

#那如果我还想传入年龄、城市等信息怎么办呢?可以把年龄设置为默认参数
def enroll(name,gender,age=16,city='BeiJing'):
    print('name:',name)
    print('gender:',gender)
    print('age:',age)
    print('city:',city)
#调用
enroll('Lucy','M')

#那么如果我调用的顺序不一致呢?

 

 

三、关键参数

#关键参数主要指实参,即调用函数时的参数传递方式,通过关键参数,实参顺序和形参顺序可以不一致
def demo(a,b,c=5):
    print(a,b,c)
#调用
demo(3,7)#3 7 5
demo(a=7,b=3,c=6)#7 3 6
demo(c=8,a=9,b=0)#9 0 8

 

 

四、可变长度参数

#可变长度参数主要有2种方式
#(1)*parameter用来接收多个实参并将其放在一个元组中
#(2)**parameter接收关键参数并存放到字典中,这里的关键参数必须要有键值对


#*parameter的用法
def demo(*parameter):
    print(parameter)
#调用
demo(1,2,3)


#**parameter的用法
def demo(**parameter):
    for item in p.items():
        print(item)
#调用
demo(x=1,y=2,z=3)
#输出
('x',1)
('y',2)
('z',3)



#假如你在开发一个用户注册功能,除了用户名和年龄是必填项,其他是可选项,例如有的用户想要输出城市,另外一个用户想输出职业等等,如何设计注册功能函数?

 

 

五、注册问题深入探究

def person(name,age,**kw):
    print('name:',name,'age:',age,'other:',kw)

#只传入必选参数
person('Marry',30)#name:Marry age:30 other:{}

#传入任意其他参数,满足注册的需求
person('Bob',39,city='BeiJing')#name:Bob age 39 other:{'city':BeiJing},在这里kw是一个字典
person('Peter',40,gender='M',job='Engineer')#name:Peter age=40 other:{'gender':M,'job':'Engineer'}

#封装为字典,再传入参数
extra = {'city':'BeiJing','job':'Engineer'}
person('Jack',25,**extra)



#那么如果我想确定可选参数的名字怎么办呢?需要命名关键字参数
#用特殊符号*分隔,*后面的视为命名关键字参数
def person(name,age,*,city,job):
    print('name:',name,'age:',age,'city:',city,'job:'job)

#调用
person('Jack',40,city='BeiJing',job='Engineer')#name:Jack age:40 city:BeiJing job:Engineer



#那么如果我输入的关键字参数既有大写又有小写,按照上面的方法出错了怎么办呢?
#考虑如果没有*是什么参数,yes,是位置参数
#这样就强制要求输入小写
def person(name,age,city,job):
    pass

 

 

六、可变长度参数

#几种不同类型的参数可以混合使用,但是不建议这样做

def func_4(a,b,c=4,*aa,**bb):
    print(a,b,c)
    print(aa)
    print(bb)

#调用
func_4(1,2,3,4,5,6,7,8,9,xx='1',yy='2','zz'='3')
#输出
(1,2,3)
(4,5,6,7,8,9)
{'xx':'1','yy':'2','zz':'3'}