python函数基础

2021-06-07 06:03

阅读:435

标签:直接   转换   原来   为什么   运行   编写   工具   主程   comm   

一、什么是函数?
这里的函数要和我们数学中的函数加以区分,python中的函数更像一种我们提前设置好功能,随取随用的工具。

二、为什么要用函数?
在没有学习函数之前,我们编写的用户登陆系统,注册、登陆验证、功能全部是写在一个循环当中,这样写的后果有两个:

  • 结构不清晰,很难读
  • 代码很长,并且有很多重复性的代码
  • 如果一个功能有改动,相应的其他地方也需要改动,维护难度极大
    而使用函数后,可以很好的解决以上问题,将不同的功能赋值到函数,主程序只需要调动函数就可以实现相应的功能。

三、怎么使用函数?
在python中,函数分为内置函数和自定义函数;

  • 内置函数就是python官方将一些常用的功能写成函数,放在python解释器中,可以直接使用,例如:open()、print()
  • 自定义函数,这就是python留给广大程序员发挥创造力的地方,可以根据自己的需要定义自己的函数。

1、定义函数
函数使用def关键字进行定义:

# 定义的语法
"""
def 函数名(参数1,参数2,...):
    ‘‘‘文档描述‘‘‘
    函数体
    return 值
"""
# 打印hello world的函数print1
def print1():
    ‘‘‘打印hello world‘‘‘
    print("hello world")

这里需要注意的地方:

  • 函数名命名规则与变量名一致i,一般使用子母加下划线,不可以使用python关键字
  • 下面的文档描述不是必须要部分,但是一般建议有,简单描述函数功能
    2、定义函数时发生了什么事情
  • 首先python申请一块内存空间,经函数体存储在内存空间中,然后将内存地址绑定给函数名;
  • 在定义阶段,函数只检查语法错误,而逻辑错误是不会检测的,只有在运行的时候才会报错
# 函数定义阶段做的事
# 语法错误,例如if语句没有:号,python会立即报错
def print1():
    if True
        print("kkk")
    print("hhh")
    
# 逻辑错误,变量aaa没有赋值,在逻辑上错误,但是语法没有错误,所以定义函数时不会报错
def print2():
    print("hhh")
    aaaa
    
print2() # 但是一旦调用函数就会报错

3、调用函数
调用函数比较简单,形式就是:函数名+()

# python函数调用
def print1():
    print("哈哈哈哈哈")
    
print1() # 调用函数

函数调用的三种方式:

  • 语句形式:foo()
  • 表达式形式:3*len(‘hello’)
  • 当中另外一个函数的参数:range(len(‘hello’))
# 函数调用的三种方式
# 语句形式
def print1():
    print("hhhhh")

print1()

# 表达式
def func():
    x = 1
    return x

y = func() + 2

# 当作另外一个函数的参数
def print_copy(x):
    print(x)

print_copy(func())

4、函数返回值
我们在使用内置函数时,有的函数有返回值,有的则没有,例如input()函数就有返回值,print()则没有,这是由函数自身的功能决定的,我们在自定义函数时,也可以指定函数的返回值。
定义函数返回值的三种方式:

  • return 值,返回一个值
  • return 值1,值2,… 返回元组:(值1,值2,…)
  • 无return,返回None,一般函数没有指定返回值,默认返回None
  • 一个函数可以有多个return,但是一旦函数遇到return,就会立刻停止运行,只有一个return能够返回值,有点类似循环中的break
# 函数返回值
#1、return 值
def sum1():
    x = 1+2+3+4+5
    return x

y = sum1() # 此时调用函数有一个返回值,可以赋值给一个变量>>>:15

# 2、return 值1,值2,返回一个元组
def func():
    x = 1
    y = 2
    z = 3
    return 1,2,3

m = func() # 调用函数返回一个元组:(1,2,3)

# 无return,返回None
def func1():
    x = 1
    print(x)
    
y = func1() # 此时函数仅具备打印功能,没有返回值:None

# 多个return
def print3():
    x = 5
    print(x)
    return x
    m = 3
    print(m)
    return m

number_1 = print3() # 因为遇到return函数就终止,所以return x后面的代码运行不到:5

5、函数参数【重点】
1)函数参数的形式

  • 形参 在函数定义阶段()内定义的变量名
  • 实参 调用阶段括号内传入的值,调用时,实参值会绑定形参,可以在函数内使用,调用完毕后,解除绑定
def func(x,y): # 这里的x,y就是形参
    print(x)
    print(y)
    
func(1,2) # 调用时,()内的1,2就是实参

2)参数类型详解

  • 位置形参;在定义阶段按照从左到右的顺序定义的参数
  • 特点:必须传值,而且位数必须一致,多一个少一个都不行
# 位置形参
def func(x,y): # x,y 就是位置形参,相当于变量名,使用时,必须指定,并且位数一致
    print(x)
    print(y)

func(1,2) 
# func(1) # 只给1个参数就会报错
  • 位置实参:在调用阶段按照从左至右依次传入的值
  • 特点:按照顺序与形参一一对应
# 位置实参
def func(x,y): 
    print(x)
    print(y)

func(1,2) # 1,2就是位置实参,按照循序依次给位置形参传值:x=1,y=2
# func(1) # 只给1个参数就会报错
  • 默认形参:在调用阶段就指定了默认值的参数
  • 特点:在函数定义阶段就已经赋值了,意味着在调用阶段可以不用为其赋值
  • ps: 可以混用位置形参与默认形参,但是位置形参必须在前
# 默认形参
def func(x,y=1): # 这里的y就是默认形参,在调用阶段可以不用给定值
    print(x)
    print(y)

func(2) # 可以不给第二个参数
func(3,6) # 也可以指定第二个参数
# func(y=6,2) # 如果以关键字实参传值,则该关键字实参不能在位置实参前面,否则报错

默认形参需要注意的问题是:
1、默认形参的值只在函数定义阶段被赋值一次
2、默认形参的值通常应该是不可变类型
看如下案例:

# 案例1
m = 100
def func(x,y=m): # 此时y被赋值m——>100的内存地址,定义完毕后,和m没有关系
    print(x)
    print(m)

m = 200 # 此时的m不会影响函数的形参
func(2) # 打印出2,100

# 案例2
m = []
def func1(x,y=m): # 这里,将列表的内存地址赋值给了y,但是列表是可变类型,会出现以下问题:
    """存储个人信息"""
    y.append(x)
    print(y)

zhangsan = func1(18) # 结果[18]
lisi = func1(20) # 结果[18,20]
# 可以看到,两次调用函数后,会互相影响结果
  • 关键字实参:按照key=value的形式向形参传值
  • 特点:可以打乱顺序,但是仍然能够为指定的形参赋值
  • ps:可以混用位置实参与管家腻子实参,
  • 注意:1、位置实参必须在关键字实参前 2、不能为同一个形参重复赋值
def func(x,y):
    print(x)
    print(y)

func(y=2,x=1)
func(1,y=2)
func(y=2,1) # 关键字实参在前面,报错
func(1,2,y=3) # 多于形参个数,报错
  • 星号“”、“**”
    可变长的参数,是指在函数调用阶段,实参个数不确定,而形参是用来接收实参传值的,为了解决实参传递溢出的问题,采用“
    ”、“**”
    ①“*”在形参中的使用,用来接收溢出的位置实参,存成元组,赋值给紧跟其后的变量名
    注意:此时的实参必须是位置实参
    ② **在形参中的使用,会接受溢出的关键字实参,存成字典,赋值给后面的变量名
# *在形参中的使用
def func(x,*y): # 这里*好接受溢出的实参,存成元组,赋值给y
    print(x)
    print(y)

func(1,2,3,4,5,6,7,8) # 结果:1,(2,3,4,5,6,7,8)

# **在形参中的使用
def func1(x,**y): # 接受溢出的关键字实参,存成字典,赋值给后面的变量名
    print(x)
    print(y)

func1(1,a=2,b=3,c=4,d=5) # 结果:1,{‘c‘: 4, ‘d‘: 5, ‘b‘: 3, ‘a‘: 2}

③*在实参中的使用,*后面跟一个被for循环遍历的类型,*会将该数据打散成位置实参
④**在实参中的使用:后面跟一个字典,**会将字典打散成关键字实参

# * 在实参中的使用
def func(x,y,z):
    print(x)
    print(y)
    print(z)

func(*[1,2,3]) # 结果1,2,3

# **在位置实参中的使用
def func1(x,y):
    print(x)
    print(y)

func1(**{"x":1,"y":2}) # 转换成:x=1,y=2

⑤*、**混合使用

def index(x,y,z):
    print(x,y,z)
    
def func(*args,**kwargs):
    index(*args,**kwargs) # 又转换成原来的形式

func(1,y=2,z=3)

作业

# 1、写函数,,用户传入修改的文件名,与要修改的内容,执行函数,完成批了修改操作
import os
def modify(txtname,oldname,newname):
    with open(txtname,"rt",encoding="utf-8")as f1,        open(".swp.txt","wt",encoding="utf-8") as f2:
        for i in f1:
            f2.write(i.replace(oldname,newname))
    os.remove(txtname)
    os.rename(".swp.txt",txtname)

modify("hhhh.txt","苹果","香蕉")

# 2、写函数,计算传入字符串中【数字】、【字母】、【空格] 以及 【其他】的个数
def count_str(str1):
    number_int = 0
    number_pha = 0
    number_none = 0
    number_other = 0
    for i in str1:
        if i == " ":
            number_none += 1
        elif i.isdigit():
            number_int += 1
        elif i.isalpha():
            number_pha += 1
        else:
            number_other += 1
    print("数字:{}".format(number_int))
    print("子母:{}".format(number_pha))
    print("空格:{}".format(number_none))
    print("其他:{}".format(number_other))

count_str("  sdffkjj3487bj$%^&*(dfgg239dbkkw7377  ds ")

#
# 3、写函数,判断用户传入的对象(字符串、列表、元组)长度是否大于5。
def judge_len(object):
    if len(object) > 5:
        print("长度大于5!")
    else:
        print("长度小于5!")

judge_len("sbhjsb")

#
# 4、写函数,检查传入列表的长度,如果大于2,那么仅保留前两个长度的内容,并将新内容返回给调用者。
def list_cheek(list_user):
    if len(list_user) > 2:
        list_1 = list_user[0:2]
        return list_1
    else:
        return list_user

x = list_cheek([1,2,3,4,5])
print(x)


#
# 5、写函数,检查获取传入列表或元组对象的所有奇数位索引对应的元素,并将其作为新列表返回给调用者。
def odd_number(object):
    list_new = []
    for i in range(0,len(object)):
        if i%2 == 1:
            list_new.append(object[i])
    return list_new

y = odd_number([1,2,3,


评论


亲,登录后才可以留言!