函数的返回值、函数的调用、函数的参数

1、函数的返回值

'''
1、什么是返回值
    返回值是一个函数的处理结果,

2、为什么要有返回值
    如果我们需要在程序中拿到函数的处理结果做进一步的处理,则需要函数必须有返回值


3、函数的返回值的应用
    函数的返回值用return去定义
    格式为:
        return 值  --------(值可以是是以数据类型)
    注意:
        1、return是一个函数结束的标志,函数内可以有多个return,
            但只要执行一次,整个函数就会结束运行------即函数下面有再多代码也不会被执行

        2、return 的返回值无类型限制,即可以是任意数据类型------------如整型、字符串、列表、元组、等
        3、return 的返回值无个数限制,即可以用逗号分隔开多个任意类型的值
            0个:返回None,ps:不写return默认会在函数的最后一行添加return None------即没有return函数代码运行完毕也会结束运行
            1个:返回的值就是该值本身
            多个:返回值是元组--------------------调用函数会将多个任意类型的值放到元组中返回
'''

# def max2(x,y): #x=3000,y=2000
#     if x > y:
#         return x #return 3000
#     else:
#         return y #reuturn 2000
#
# res=max2(3000,2000)                         #函数正常调用,赋值给一个变量,可以拿到一个返回值
#
# # annual_salary=res * 12                    #函数当做一个参数,做进一步的处理如运算
#
# annual_salary=max2(max2(3000,2000),3000)    #将函数当做一个参数,传给函数做进一步的调用
#
# print(annual_salary)




# def foo():
#     print(1)
#     print(2)
#     print(3)
#     return [1,2,3],'a',('a','b'),{1,2}   #return可以返回任意数据类型,返回多个值,函数遇到return整个函数就会结束
#     print(4)
#     print(5)
#     print(6)
#
# res=foo()
# print(res)


# def bar():
#     print(1)
#     print(1)
#     print(1)
#     print(1)
#     return         #return没有写返回值,默认返回值为None
#     print(2)
#     print(3)
#     print(4)
#
# res=bar()
# print(res)

2、函数的调用

'''
1 什么是调用函数
    函数名(...)即调用函数,会执行函数体代码,直到碰到return结束或者一直运行完毕所有代码

2 为何要调用函数
    用函数的功能

3、函数调用分为三种形式
    max2(1,2)                             #直接调用函数
    res=max2(3000,2000) * 12              #当做参数做进一步处理
    res=max2(max2(1000,2000),3000)        #当做函数的参数做进一步的调用
'''

# def foo():
#     print(1)
#     print(2)
#     print(3)
#     return None              #None不写,默认就为None
# res=foo()
# print(res)


def max2(x,y):
    if x > y:
        return x
    else:
        return y

# 调用函数的三种形式
#形式一:
# max2(1,2)

#形式二:
# res=max2(3000,2000) * 12
# print(res)

#形式三:
res=max2(max2(1000,2000),3000)
print(res)

3、函数的参数

#总的分类:
# #1、形参:在函数定义阶段括号内定义的参数,称之为形式参数,简称形参,本质就是变量名
# def foo(x,y): #x=1,y=2    #x、y本质就是变量名,也即形参
#     print(x)
#     print(y)
# #2、实参:在函数调用阶段括号内传入的值,称之为实际参数,简称实参,本质就是变量的值
# foo(1,2)                  #1、2本质就是变量的值
#

#详细的分类:
#一、位置参数:
#位置形参:在函数定义阶段,按照从左到右的顺序依次定义的形参,称之为位置形参
#特点:但凡是按照位置定义的形参,都必须被传值,多一个不行,少一个也不行----------多一个少一个均会报错
# def foo(x,y):
#     print('x:',x)
#     print('y:',y)

#位置实参:在函数调用阶段,按照从左到右的顺序依次定义的实参,称之为位置实参
#特点:按照位置为对应的形参依次传值-----------调换位置传入的值也会发生变化,而关键字实参调换顺序就不会影响值的传入结果
# foo(1,2)              #------传入的结果是不一样的
# foo(2,1)


#二、关键字实参:在调用函数时,按照key=value的形式为指定的参数传值,称为关键字实参
#特点:可以打破位置的限制,但仍能为指定的形参赋值---------即不会影响传入的结果
# foo(y=2,x=1)          #二者调换顺序并不会影响传入值得结果

#注意:
#1、可以混用位置实参与关键字实参,但位置实参必须放在关键字实参的前面
# foo(1,y=2)            #---------位置实参放在关键字参数的前面即左边
# foo(y=2,1)            #---------位置参数放在关键字参数的后面会报错,SyntaxError: positional argument follows keyword argument

#2、可以混用,但不能对一个形参重复赋值
# foo(1,y=2,x=10)       #---------形参x被重复传值,所以会报错


#三:默认参数:在函数定义阶段,就已经为形参赋值,该形参称为默认形参
#特点:在定义阶段就已经被赋值,意味着在调用可以不用为其赋值
# def foo(x,y=10):      #---------形参有默认值,调用阶段,可以不用给其进行传值,会以默认参数为准,如给默认形参传值,则会以传入的值为准
#     print('x:',x)
#     print('y:',y)

# foo(1)                #y没有传值则会以默认的为准
# foo(1,3)              #默认形参也被重新传值,则会以传入的3为准
# 注意:
#1、位置形参必须放到默认形参的前面,否则报语法错误
# def foo(x=1,y):       #默认形参放在位置形参的前面会报错----SyntaxError: non-default argument follows default argument
#     pass

#2、默认参数的值只在定义阶段赋值一次,即默认参数的值在函数定义阶段就已经固定死了

# m=10
# def foo(x=m,y=11):
#     print(x)
#     print(y)
# m=111111111111111111111111111   #----------默认参数的值在定义阶段就已经固定死了,所以该m的是并不会影响调用的结果
# foo()

#3、默认参数的值通常应该定义不可变类型---------定以为可变类型,会产生耦合的现象

# def register(name,hobby,hobbies=[]):   #默认参数为可变类型,产生耦合现象
#     hobbies.append(hobby)
#     print('%s的爱好' %name,end=':')
#     print(hobbies)
#
# register('egon','play')           #egon的爱好:['play']
# register('alex','piao')           #alex的爱好:['play', 'piao']
# register('lxx','烫头' )           #lxx的爱好:['play', 'piao', '烫头'],lxx只有烫头的爱好,而结果却继承了egon和alex的爱好

# def register(name,hobby,hobbies=None):
#     if hobbies is None:
#         hobbies=[]
#     hobbies.append(hobby)
#     print('%s的爱好' %name,end=':')
#     print(hobbies)
#
# register('egon','play')
# register('alex','piao')
# register('lxx','烫头')



#总结:
#实参的应用:取决于个人习惯,-------自己喜欢用哪种实参都可以为形参进行传值
#形参的应用:
#1、位置形参:大多数情况下的调用值都不一样,就应该将该参数定义成位置形参
#2、默认形参:大多数情况下的调用值都一样,就应该将该参数定义成默认形参
# def register(name,age,sex='male'):         #人的性别大多数人都一样,所以设置为默认参数,不用每次调用都给其传值
#     print(name)
#     print(age)
#     print(sex)
#
#
# register('egon',18,)
# register('大脑门',73,'female')            #设置默认参数的好处,调用时只需要给少数性别不一样的进行传值就可以了
# register('小脑门',84,)
# register('大高个',18,)



#四:可变长参数:指的是在调用函数时,传入的参数个数可以不固定-------如计算几个数的和
#而调用函数时,传值的方式无非两种,一种位置实参,另一种时关键字实参
#所以对应着,形参也必须有两种解决方案,来分别接收溢出的位置实参(*)与关键字实参(**)

#1、形参中某个参数带*
#形参中的*会将溢出的位置实参全部接收,然后存储元组的形式,然后把元组赋值给*后的变量名
# def foo(x,y,*z): #x=1,y=2,z=(3,4,5,6,7)-------*接收所有溢出的实参,并将其传承元组赋值给变量z
#     print(x)
#     print(y)
#     print(z)
# foo(1,2,3,4,5,6,7)

# 应用---------------计算若干个数的和
# def my_sum(*nums):        #-----*接收传进来的所有的位置实参,存成元组的形式
#     res=0                 #运算的初始值为0
#     for num in nums:      #for循环,将元组中所有的参数取出来,进行数学运算
#         res+=num          #运算的结果返回给调用者
#     return res
#
# print(my_sum(1,2,3,4,5))  #将溢出的所有值都让*接收

# 2、实参中的参数也可以带*
# 实参中带*,*会将该参数的值循环取出,打散成位置实参
#ps:以后但凡碰到实参中带*的,它就是位置实参,应该立马打散成位置实参去看
# def foo(x,y,z):
#     print(x,y,z)
#
# foo(1,*[2,3]) #foo(1,2,3)          #-----*将列表中的数循环取出,打散成位置参数,传给位置形参
# foo(1,*'he') #foo(1,'h','e')       #-----*将字符串中的字符循环取出,打散成位置参数,传给位置形参
# foo(1,*(2,3,4)) #foo(1,2,3,4)      #-----*将元组中的数循环取出,打散成位置参数,传给位置形参------但打散的位置实参超出位置形参的个数,所以会报错

# def foo(x,y,z,*args):
#     print(x)
#     print(y)
#     print(z)
#     print(args)                     #打印结果:(4, 5, 6, 7, 8, 9, 10, 11)
# #
# foo(1,2,3,4,5,6,7,*[8,9,10,11]) #foo(1,2,3,4,5,6,7,8,9,10,11)  #打散传给位置形参,溢出的将会被形参中的*接收,存成元组的形式
#注意:约定俗成形参中的*变量名的写法都是:*args



#1、形参中某个参数带**
#形参中的**会将溢出的关键字实参全部接收,然后存储字典的形式,然后把字典赋值给**后的变量名
# def foo(x,y,**z): #x=1,y=2,z={'c':5,'b':4,'a':3}------**会接收溢出的所有关键字实参,并将其存成字典的形式赋值给变量z
#     print(x)
#     print(y)
#     print(z)                          #打印结果:{'a': 3, 'b': 4, 'c': 5}
# foo(1,2,a=3,b=4,c=5)

# 2、实参中的参数也可以带**,该参数必须是字典
# 实参中带**,**会将该参数的值循环取出,打散成关键字实参
#ps:以后但凡碰到实参中带**的,它就是关键字实参,应该立马打散成关键字实参去看
# def foo(x,y,z):
#     print(x)
#     print(y)
#     print(z)
#
# foo(1,2,**{'a':1,'b':2,'c':3,'z':3}) #foo(1,2,c=3,b=2,a=1,z=3)   #打散后的实参已经超过了形参能够接收读的个数,所以会报错
# foo(**{'z':3,'x':1,'y':2}) #foo(y=2,x=1,z=3)-----**是实参中的字典打散成关键字参数

#注意:约定俗成形参中的**变量名的写法都是:**kwargs

# def index(name,age,sex):
#     print('welecome %s:%s:%s to index page' %(name,age,sex))     #------打印结果:welecome egon:18:male to index page
#
# def wrapper(*args,**kwargs): #args=(1,),kwargs={'x': 1, 'y': 2, 'z': 3}
#     index(*args,**kwargs) #index(*(1,),**{'x': 1, 'y': 2, 'z': 3}) #index(1,x=1,y=2,z=3)
#
# wrapper(name='egon',sex='male',age=18)   #该关键字参数会原封不动的传给其内部的index函数,当做其实参,在原封不动的传给index函数的形参
# #

#五 命名关键字形参:在函数定义阶段,*后面的参数都是命名关键字参数(**)
# 特点:在传值时,必须按照key=value的传,并且key必须命名关键字参数指定的参数名
# def register(x,y,z,**kwargs): #kwargs={'b':18,'a':'egon'}
#     if 'name' not in kwargs or 'age' not in  kwargs:
#         print('用户名与年龄必须使用关键字的形式传值')
#         return
#     print(kwargs['name'])                   #关键字变量名是‘name’则会被打印,否则不会打印出来
#     print(kwargs['age'])
# # register(1,2,3,a='egon',b=18)             #关键字实参,会被**接收存储成字典的形式,并赋值给变量kwargs
# register(1,2,3,name='egon',age=18)          #关键字实参,会被**接收存储成字典的形式,并赋值给变量kwargs


# def register(x,y,z,*args,name='egon',age):  #命名关键字参数,*后面的形参,均为命名关键字参数,也意味着命名关键字参数,必须按照
#     print(args)                             #(4, 5, 6, 7)
#     print(name)                             #egon----------name='egon'在*后面也是命名关键字参数,并不是默认参数
#     print(age)                              #18
# register(1,2,3,4,5,6,7,age=18)
# register(1,2,3,4,5,6,7,c=18) #没有按照命名关键字进行传值,所以会报错-----TypeError: register() got an unexpected keyword argument 'c'
#



# def foo(x,y=1,*args,z=1,a,b,**kwargs):
#     pass
# def foo(x,*args,y=1,z=1,a,b,**kwargs):
#     pass
# def foo(x,y=1,**kwargs,*args,z=1,a,b):   #*后面为关键字参数,**相当于默认参数,而*相当于位置形参,而位置形参要放在默认参数的前面,所以会报错
#     pass


# # foo(1,*[1,2,3],a=1,**{'x':1,'y':2}) #foo(1,1,2,3,a=1,y=2,x=1)  #将实参中的*和**打散成位置实参和关键字实参在进行传值
# foo(1,a=1,*[1,2,3],**{'x':1,'y':2}) #foo(1,a=1,1,2,3,y=2,x= 1)   #关键字参数a=1在*打散后位置参数的前面所以会报错

# foo(1,2)
# foo(x=1,y=2)


# open('a.txt','w',encoding='utf-8')   #Ctrl+鼠标左键,查看源代码可以看到如下,'a.txt'为位置实参,'w'为位置实参,默认的为位置形参mode='r',
#按顺序传值,所以'utf-8'要指定为关键字实参
#-----def open(file, mode='r', buffering=None, encoding=None, errors=None, newline=None, closefd=True):

猜你喜欢

转载自www.cnblogs.com/sui776265233/p/9145956.html
今日推荐