函数基础

阅读提示:

  • 为什么使用函数
  • 定义函数
  • 调用函数
  • 函数的参数
  • 练习

一、为什么使用函数?

  一、为何要使用函数  

#在不使用函数时,编写的程序有如下的问题:
#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')
1
'''
写函数,检查字典的每一个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]))
2
'''
写函数,计算传入字符串中【数字】、【字母】、【空格] 以及 【其他】的个数
'''

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)
3

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2017-12-19 14:14  追逐不可能β③  阅读(224)  评论(0编辑  收藏  举报