函数的返回值、函数的调用、函数的参数
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):
python之基础知识大全