函数基础
阅读提示:
- 为什么使用函数
- 定义函数
- 调用函数
- 函数的参数
- 练习
一、为什么使用函数?
一、为何要使用函数
#在不使用函数时,编写的程序有如下的问题: #1.组织结构不清晰,可读性差 #2. 代码冗余(遇到重复的功能只能重复编写实现代码) #3.可扩展性差(功能需要扩展时,需要找出所有实现该功能的地方修改之,无法统一管理且维护难度极大 )
二、函数是什么?
函数就是具备某一功能的程序,比如现实生活中修理工需要实现准备好工具箱里面放好锤子,扳手,钳子等工具,然后遇到锤钉子的场景,拿来锤子用就可以,而无需临时再制造一把锤子。
修理工===》 程序员
扳手(…)===》 函数
要想使用工具,需要事先准备好,然后拿来就用且可以重复使用
python中,函数就是定义好的程序,我们直接拿过来重复使用即可,我们在python中已经见过了函数,比如print,len()……等!
三、函数的分类
#1、内置函数 为了方便我们的开发,针对一些简单的功能,python解释器已经为我们定义好了的函数即内置函数。对于内置函数,我们可以拿来就用而无需事先定义,如len(),sum(),max() ps:我们将会在最后详细介绍常用的内置函数。 #2、自定义函数 很明显内置函数所能提供的功能是有限的,这就需要我们自己根据需求,事先定制好我们自己的函数来实现某种功能,以后,在遇到应用场景时,调用自定义的函数即可。例如
二、函数的定义
一、如何定义函数
在了解函数定义之前我们其实已经学习过了类似函数的定义,如x=2,相当于一个个变量,不过函数的定义有自己的定义方式。
#函数的定义使用 def 开头: #自定义函数:def 语法: def 函数名(参数1,参数2,...): """注释""" 函数体 return 返回值
def auth(user:str,password:str)->int: ''' auth function :param user: 用户名 :param password: 密码 :return: 认证结果 ''' if user == 'egon' and password == '123': return 1 # print(auth.__annotations__) #{'user': <class 'str'>, 'password': <class 'str'>, 'return': <class 'int'>} user=input('用户名>>: ').strip() pwd=input('密码>>: ').strip() res=auth(user,pwd) print(res)
二、函数的使用原则:先定义,在调用
函数即“变量”,“变量”必须先定义后引用。未定义而直接引用函数,就相当于在引用一个不存在的变量名 #测试一 def foo(): print('from foo') bar() #bar的函数未定义,所以报错 foo() #报错 #测试二 def bar(): print('from bar') def foo(): print('from foo') bar() foo() #正常 #测试三 def foo(): print('from foo') bar() def bar(): print('from bar') foo() #会报错吗? #结论:函数的使用,必须遵循原则:先定义,后调用 #我们在使用函数时,一定要明确地区分定义阶段和调用阶段 #定义阶段 def foo(): print('from foo') bar() def bar(): print('from bar') #调用阶段 foo()
三、 函数在定义阶段都干了哪些事?
#只检测语法,不执行代码 #定义阶段 # sex='male' # def auth(): # sex # # name=input('name>>: ').strip() # password=input('password>>: ').strip() # if name =='egon' and password == '123': # print('login successfull') # else: # print('user or password err') # # #调用阶段 # auth()
也就说,语法错误在函数定义阶段就会检测出来,而代码的逻辑错误只有在执行时才会知道
四、定义函数的三种形式
#1、无参:应用场景仅仅只是执行一些操作,比如与用户交互,打印 #2、有参:需要根据外部传进来的参数,才能执行相应的逻辑,比如统计长度,求最大值最小值 #3、空函数:设计代码结构
#无参函数的定义及使用 #交互模式的输入,不需要参数 # def auth(): # name=input('name>>: ').strip() # if not name: continue if 的布尔值判断 # password=input('password>>: ').strip() # if name =='egon' and password == '123': # print('login successfull') # else: # print('user or password err')
#有参函数的定义及使用 #比较两个数字的大小 # def my_max(x,y): # if x >= y: # print(x) # else: # print(y) # # my_max(1,2)
#空函数的定义及使用 #空函数主要用于程序的代码框架的实现 #实现自动登录的代码 #def auth(): pass #实现上传 def put(): pass #下载 def get(): pass #ls 查看 def ls(): pass
三、函数调用
函数在定义阶段有三种形式,那么调用是不是也是三种形式呢?
一、函数的调用
函数的调用:函数名加括号 1 先找到名字 2 根据名字调用代码 # def foo(): # print('first') #foo()
二、函数的返回值
什么时候该有返回值?
调用函数,经过一系列的操作,最后要拿到一个明确的结果,则必须要有返回值
通常有参函数需要有返回值,输入参数,经过计算,得到一个最终的结果
什么时候不需要有返回值?
调用函数,仅仅只是执行一系列的操作,最后不需要得到什么结果,则无需有返回值
通常无参函数不需要有返回值
python 的在函数中的返回值主要用retunrn 做为返回值的调用。
#return的特点: #1、 函数内可以有多个return,但是只能执行一次return #2、 执行return函数就立刻结束,并且return的后值当做本次调用的结果返回 # def foo(x,y): # return x+y # # res=foo(1,2) # # def my_max(x,y): # if x >= y: # return x # else: # return y # # res=my_max(1,2) # print(res) # def foo(): # print('first') # return 1 # print('second') # return 2 # print('third') # return 3 # # res=foo() # print(res) #1、返回的值没有类型限制 # def bar(): # print('from bar') # # def foo(): # return bar # print(foo() is bar) #2:return返回值的个数 #2.1: 没有return:默认返回None #2.2:return 值:值本身 #3.3: return 多个值:返回一个元组,使用逗号分隔 def foo(): # pass return 1,'a',[1,2] print(foo(),type) #显示出返回值的类型
三、函数调用的三种形式
1 语句形式:foo() 2 表达式形式:3*len('hello') 3 当中另外一个函数的参数:range(len('hello'))
def my_max(x,y): if x >= y: return x else: return y # res1=my_max(1,2) #语句调用 # res2=my_max(1,2)*10 #表达式 # res3=my_max(my_max(1,2),3) #函数做另一个函数的参数 # print(res3) #还是函数做另一个函数的参数 range(len([1,2,3])) print(range(len([1,2,3])))
四、函数的参数
函数的参数,总体有两大类,分别是形参和实参。
函数的参数分类两种: #形参:在定义阶段括号内指定的参数,相当于变量名 #实参:在调用阶段括号内传入的值称之为实参,相当于值 #在调用阶段,实参的值会绑定给形参,在调用结束后解除绑定 # def foo(x,y): #x=1,y=2 # print(x,y) # # foo(1,2)
那么在python 中参数有具体分为以下类型:
在python中参数的分类: #1、位置参数:按照从左到右的顺序依次定义的参数 #位置形参:必须被传值,多一个少一个都不行 #位置实参:与形参一一对应传值 # def foo(x,y): # print(x,y) # # foo(2,1) #2、关键字参数:在函数调用时,按照key=value的形式定义的实参 #特点:指名道姓地给形参传值,不再依赖与位置 def foo(name,age,sex): print(name,age,sex) # foo('egon',18,'male') # foo(sex='male',age=18,name='egon',) #注意: #1、 关键字实参必须在位置实参的后面 #2、 不能为同一个参数赋值多次 # foo('egon',sex='male',age=18,name='egon') #3、默认参数:在函数定义阶段,就已经为形参赋值了 #特点:定义阶段已经有值意味着调用阶段可以不用传值 #位置参数通常用于经常变化的参数,而默认参数指的是大多数情况下都一样的 # def foo(x,y=1): # print(x,y) # foo(1,2) # foo(y=3,x=1) # foo(111) # foo(x=1111) # def register(name,age,sex='male'): # print(name,age,sex) # # register('egon1',18) # register('egon2',18) # register('egon3',18) # register('alex',38,'female') #注意: #1、默认参数必须放到位置形参的后面 # def register(name,sex='male',age,): # print(name,age,sex) #2、默认参数的值只在定义时被赋值一次 #3、默认的参数的值通常应该是不可变类型 # res=1 # def foo(x,y=res): # print(x,y) # # res=10 # foo('aaaaaaaa') #4 可变长参数:在调用函数时,实参值的个数不固定 #实参的形式有:位置实参和关键字实参, #形参的解决方案:*,** #*args的用法 # def foo(x,y,*args): #z=(3,4,5,6) # print(x,y) # print(args) # # # foo(1,2,3,4,5,6) # # foo(1,2,*[3,4,5,6]) #foo(1,2,3,4,5,6) # foo(*[1,2,3,4,5,6]) #foo(1,2,3,4,5,6) # def foo(x,y): # print(x,y) # # foo(*(1,2)) #foo(1,2) #**kwargs # def foo(x,y,**kwargs): #kwargs={'c':5,'a':3,'b':4} # print(x,y) # print(kwargs) # # # foo(y=2,x=1,a=3,b=4,c=5) # # foo(y=2,**{'c':5,'x':1,'b':4,'a':3}) #foo(y=2,a=3,c=5,b=4) # def foo(name,age): # print(name,age) # foo(**{'name':'egon','age':18}) # foo({'name':'egon','age':18}) # def bar(x,y,z): # print(x,y,z) # # def wrapper(*args,**kwargs): #args=(1,),kwargs={'z':2,'y':3} # # print(args,kwargs) # bar(*args,**kwargs) #bar(*(1,),**{'z':2,'y':3}) #bar(1,z=2,y=3,) # # wrapper(1,z=2,y=3) #命名关键字参数:指的是定义在*后的参数,该参数必须被传值(除非有它有默认值),而且必须按照key=value的形式传值 # def foo(x,y,*args,m=100000,n): # print(x,y) # print(args) # print(m,n) # # foo(1,2,3,n=4,)
'' 要求:写函数,用户传入要修改的文件名且与要修改的内容,执行函数,完成批了修改操作 解决思路: 1.先定义一个函数,函数的参数是:传入文件名,修改的文件内容(旧字段,新字段)如: def modify_file (filename,old,new) 2.编写出修改文件的程序 3.然后使用函数调用,直接修改如: def modify_file (a.txt,shao,liu) 打开a.txt,修改a.txt里的shao为刘。 ''' import os def modify_file(filename,old,new): with open(filename,'r',encoding='utf-8') as f,\ open('a.txt.swap','a',encoding='utf-8') as w: for i in f: if old in i: n=i.replace(old,new) w.write(n) w.write(i) os.remove(filename) os.rename('a.txt.swap',filename) modify_file('a.txt','liu','shao')
''' 写函数,检查字典的每一个value的长度,如果大于2,那么仅保留前两个长度的内容, 并将新内容返回给调用者。 dic = {"k1": "v1v1", "k2": [11,22,33,44]} ''' # def func3(dic): # d={} # for k,v in dic.items(): # if len(v) > 2: # d[k]=v[0:2] # # print(k) # return d # print(func3({'k11':'abcdef','k2':[1,2,3,4],'k3':('a','b','c')})) """ 写函数,检查获取传入列表或元组对象的所有奇数位索引对应的元素,并将其作为新列表返回给调用者。 """ # def func2(seq): # return seq[::2] # print(func2([1,2,3,4,5,6,7]))
''' 写函数,计算传入字符串中【数字】、【字母】、【空格] 以及 【其他】的个数 ''' def check_str(msg): res={ 'num':0, 'string':0, 'space':0, 'other':0, } for s in msg: if s.isdigit(): res['num']+=1 elif s.isalpha(): #检测字符串是否只由字母组成。 res['string']+=1 elif s.isspace(): #检测字符串是否只由空格组成 res['space']+=1 else: res['other']+=1 return res res=check_str('hello name:aSB passowrd:alex3714') print(res)