Bootstrap

python中的函数

一.回顾

需求:编写一段python,生成一个四位随机验证码

前提:定义一个字符串str1=“0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ”

python代码:

1.思考:如果只生成4个字符的验证码,如果只保证从字符串中读取四次,(while循环,for循环)

2.如何随机的从str1字符串中读取4个字符?(random模块,random.randint()生成随机数

3.如何从字符串中提取出某个字符?答:使用索引下标,str1[索引下标]

import random
str1='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
code=''
for i in range(4):
    index=random.randint(0,len(str1)-1)
    code+=str1[index]
print(code)
二.Python中函数的作用与使用步骤
1.为什么需要函数

重复使用某一功能

2.什么是函数

函数是一个被命名的、独立的、完成特定功能的代码段,其可能给调用它的程序一个返回值

被命名的:在Python中,大部分函数都是有名函数

完成特定功能的代码段:函数的功能要专一,专门为了完成某个功能而定义

返回值:当函数执行完毕后,其可能会返回一个值给函数的调用处

3.函数的定义
 def 函数名(参数):    
 函数体
4.函数的调用
函数名(参数)

1.不同的需求,参数可有可无

2.在python中,函数必须先定义后使用

5.通过一个例子引入函数
6.聊聊return

默认情况下只返回第一个return值

思考:如果一个函数如些两个return (如下所示),程序如何执行?

def return_num():    
    return 1    
    return 2
result = return_num()
print(result)  # 1

答:只执行了第一个return,原因是因为return可以退出当前函数,导致return下方的代码不执行。

:如果一个函数要有多个返回值,该如何书写代码?

答:==采用元组形式

def return_num():
    return 1,2

a=return_num()
print(a)
print(type(a))

输出:
(1, 2)
<class 'tuple'>
7.

思考:封装一个函数,参数有两个num1,num2,求两个数的四则运算结果

四则运算:加减乘除

def jisuan(num1,num2):
    a=num1+num2
    b=num1-num2
    c=num1*num2
    d=num1/num2
    return a,b,c,d

a=int(input('输入第一个数'))
b=int(input('输入第二个数'))
result=jisuan(a,b)
print(result)
三.Python函数中的说明文档
1.什么是说明文档

思考:定义一个函数后,程序员如何书写程序能够快速提示这个函数的作用?

答:注释

思考:如果代码多,我们是不是需要在很多代码中找到这个函数定义的位置才能看到注释?如果想更方便的查看函数的作用怎么办?

答:函数的说明文档(函数的说明文档也叫函数的文档说明)

2.定义函数的说明文档
def jisuan(num1,num2):
    """hsnnndd"""
    
help(jisuan)
即可输出说明文档
3.封装函数,用于生成指定长度的验证码
def generate_code(long):
    import random
    str2=''
    str1 = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
    for i in range(long):
        index=random.randint(0,len(str1)-1)
        str2+=str1[index]
    return str2

print(generate_code(1))
四.函数的嵌套
1.什么是函数的嵌套

所谓函数嵌套调用指的是一个函数里面又调用了另外一个函数。

2.函数嵌套的基本语法
def funcb():
    print('-'*20)
    print('这是funcb的功能部分')
    print('-'*20)

def funca():
    print('-' * 20)
    funcb()
    print('这是funca的功能部分')
    print('-' * 20)

funca()


#输出:
--------------------
--------------------
这是funcb的功能部分
--------------------
这是funca的功能部分
--------------------

执行流程:执行A在外,执行到B的时候,同时执行B

3.PyCharm调试小技巧

Step over(F8):代码一步步向下执行,但是遇到了函数以后,不进入函数体内部,直接返回函数的最终执行结果。

Step into(F7):代码一步一步向下执行,但是遇到了函数以后,进入到函数体内部,一步步向下执行,直到函数体的代码全部执行完毕。

4.通过一个案例去描述函数嵌套
五.函数的应用案例

案例一:使用方法打印一条横线

print('-'*20)

案例2:升级,根据输入值,生成指定数量的横线

def hx(num,long):
    """第一个为数量,第二个为长度"""
    for i in range(num):
        print('-'*long)
hx(3,3

案例3:封装一个函数,求三个数的平均值

def average(a,b,c):
    """求三个数的平均值"""
    s=a+b+c
    return s/3

print(average(1,2,3))
help(average)

练习题:编写一个函数,有一个函数str1,输入信息如 ‘1,2,3,4,5’,使用函数对其进行处理,要求最终返回结果为 ‘5-4-3-2-1’

字符串反转拼接,采用切片的方式进行反转

def num(a,b,c,d,e):
    s=e-d-c-b-a
    return s

print(num(1,2,3,4,5))

可通过替换str.replace(‘,’ , ‘-’)

六,变量的作用域
1.什么是变量的作用域

变量作用域指的是变量的作用范围(变量在哪里可用,在哪里不可用),主要分为两类:局部变量和全局变量。

2.局部变量与全局变量

在python中,定义在函数外部的变量就称之为全局变量;定义在函数内部变量就称之为局部变量

#定义在函数外部变量
num=10

#定义一个函数
def func():
   #函数体
   #定义在函数体内的局部变量
   i=1
3.变量的作用域范围

全局变量:在整个程序内都可以使用

局部变量:在函数的调用过程中,开始定义,函数运行过程中生效,函数执行完毕后,销毁


普及小知识:计算机的垃圾回收机制

4.global关键字

思考:如果有一个数据,在函数A和函数B中都要使用,该怎么办?

答:将这个数据存储在一个全局变量里面。

案例:如果把通讯录管理系统更改为模块化编程模式(程序=>函数),面临问题

#定义全局变量
info=[]

#定义funcA函数
def funcA():
    # 向info全局变量中添加数据
    info.append({...})
    
#定义funcB函数
def funcB():
    # 共享全局作用域中的全局变量info
    for i in info:
        ...

这会产生一个问题:我们能不能在局部作用域对全局变量进行修改呢:

#定义全局变量
num=10

#定义一个函数func
def func():
    #尝试在局部作用域修改全局变量
    num=20
    print(num)

#调用函数func
func()
print(num)

#输出:
20
10

由运行结果知:不能在局部作用域对全局变量进行修改,所有一定要进行修改的,需要使用global关键字

#定义全局变量
num=10

#定义一个函数func
def func():
    #尝试在局部作用域修改全局变量
    #使用gloabal修改全局变量
    global num
    num=20
    print(num)

#调用函数func
func()
print(num)

输出:
20
20
5,多函数之间数据的共享
#定义全局变量
info=[]

#定义funcA函数
def funcA():
    #global
    gloabal info
    # 向info全局变量中添加数据
    info.append({...})
    
#定义funcB函数
def funcB():
    # 共享全局作用域中的全局变量info
    for i in info:
        ...
6,把函数返回值作为另外一个函数的参数
def test1():
    return 30

def test2(num):
    print(num)

result=test1()
test2(result)

输出:30
七,参数的进阶
1,函数的参数

在函数定义与调用时,我们可以根据自己的需求来实现参数的传递。

两种形式:实参,形参

形参:在函数定义时,所编写的参数就称之为形式参数

实参:在函数调用时,所传递的参数就称之为实际参数

def great(name):
    #name就是在函数greet定义时,所编写的参数(形参)
    return name+',您好'

#调用函数
name='老王'
greet(name)  #在函数调用时,所传递的函数就是实际参数

注意:虽然我们在函数传递时,喜欢使用相同的名称作为参数名称,但是两者的作用范围是不同的

2,函数的参数类型
1.位置参数

理论上,在函数定义时,我们可以定义多个参数。但是在函数调用时,我们也应该传递多个参数,而且正常情况下,其要一一对应

def user_info(name,age,address):
    print(f'我的名字是{name},今年{age}岁了,住在{address}')

user_info('刘占豪','18','舞钢')

定义与调用时必须一一对应,实际参数与形式参数在位置上必须一一对应,强调的是参数传递时的位置

2.关键字参数(Python特有)

函数调用,通过“键=值”形式加以指定。可以让函数更加清晰、容易使用,同时也清除了参数的顺序需求。

def user_info(name,age,address):
    print(f'我的名字是{name},今年{age}岁了,住在{address}')

#调用函数时使用关键词函数
user_info(age='18',name='刘占豪',address='舞钢')

与上边位置参数输出效果一样,不用强调位置

3.函数定义时的缺省参数(参数默认值)

缺省参数也叫默认参数,用于定义函数,为参数提供默认值,调用函数时可不传该默认参数的值(注意:所有位置参数必须出现在默认参数前,包括函数定义和调用)

def user_info(name,age,gender='男'):
    print(f'我的名字是{name},今年{age}岁了,性别{gender}')

# user_info('lilin',23,'男')
# user_info('liling',25,'男')

#全为男,默认为男,不进行传递

user_info('lilin',23)
user_info('liling',25)
user_info('waner',18,'女')

不填写时默认为男,填写后以填写的为准,如女

谨记:我们在定义缺省参数时,一定要把其写在参数列表的最右侧

4.不定长参数

不定长参数也叫可变参数。用于不确定调用的时候会传递多少个参数(不传参也可以)的场景。此时,可用包裹(packing)位置参数,或者包裹关键字参数,来进行参数传递,会显得非常方便。

1,包裹(packing)位置参数
def user_info(*args):
    print(args)
    print(f'我的名字是{args[0]}{args[1]}岁了,住在{args[2]}')
    #实现格式化输出

user_info('Tom','23','美国纽约')

传进的所有参数都会被args变量收集,它会根据传进参数的位置合并为一个元组(tuple),args是元组类型,这就是包裹位置传递。

元组形式,还应注意位置

2,包裹关键字参数

kw=keywor+args

def user_info(**kwargs):
    print(kwargs)

user_info(name='Tom',age=23)

字典形式,参数传递没有顺序要求,格式要求为key:value

综上:无论是包裹位置传递还是包裹关键字传递,都是一个组包的过程。

组包:把多个数据组成元组或字典

八,Python拆包(元组和字典)
1.什么是拆包

Python拆包:就是把元组或字典中的数据单独拆分出来,然后赋予给其他的变量

拆包: 对于函数中的多个返回数据, 去掉元组, 列表 或者字典直接获取里面数据的过程

☆ 2.拆包tuple元组:
def func():
    #返回元组
    return 10,20

#定义两个变量,接受元组中的两个数据
num1,num2=func()
print(num1)
print(num2)

num1为返回元组的第一个数据,num2为返回元组的第二个数据
☆ 3,拆包dict字典

记住:字典拆包,只能把每个元素的key拆出来

dict1={'name':'刘占豪','age':'18'}
#拆包
a,b=dict1
print(a)
print(b)

#获取数据
print(dict1[a])
print(dict1[b])

输出:
name
age
刘占豪
18
4,拆包的应用案例

案例一:使用至少三种方式交换两个变量的值

#第一种方式。引入临时变量
c1=10
c2=2

#引入temp
temp=c1
c1=c2
c2=temp

print(c1,c2)

输出:2 10
#使用加法与减法运算交换两个值
c1=10
c2=2

c1=c1+c2
c2=c1-c2
c1=(c1-c2)

print(c1,c2)

只有python才具有的方法,拆包

#第三种方法
c1=10
c2=2

c1,c2=c2,c1
print(c1,c2)

案例2:python中数据传递案例

def func(*args,**kwargs):
    print(args)
    print(kwargs)

#元组
tuple=(10,20,30)

#字典
dict1={'first':20,'second':30,'third':30}

#把元组传递给*args,把字典传给**kwargs
#把元组传递给*args,必须在tuple前加*,
#把字典传给**kwargs,必须在dict1前加**
func(*tuple,**dict1)

输出:(10, 20, 30)
{'first': 20, 'second': 30, 'third': 30}
九,使用python编辑通讯录系统
1,通讯录系统的最终效果
2,需求分析

上述六个功能

添加学员信息

删除学员信息

修改学员信息

查询学员信息

遍历所有学员信息

退出系统

3,功能实现步骤

① 显示功能界面

② 用户输入功能序号

③ 根据用户输入的功能序号,执行不同的功能(函数)

定义函数

调用函数

4,模块化的编程思想

最早的编程思想,其强调把一个系统分解为若干个功能,每个功能就是一个模块(函数)。当所有功能开发完毕后,则系统就完成了

students=[]

def add_student():
    global students
    student={}
    student['name']=input('请输入学生的姓名')
    student['age'] = input('请输入学生的年龄')
    student['address'] = input('请输入学生的住址')
    students.append(student)
    print('学员信息添加成功')
    print(students)

def del_student():
    global students
    name=input('请输入你所要删除学员的姓名')
    for i in students:
        if i['name']==name:
            students.remove(i)
            print('删除成功')
            break
    else:
        print('你输入的信息不存在')
    print(students)

def replace_student():
    global students
    name=input('请输入你所要修改的姓名')
    for i in students:
        if i['name']==name:
            i['name']=input('请输入所要修改的姓名')
            i['age'] = input('请输入所要修改的年龄')
            i['address'] = input('请输入所要修改的地址')
            print('修改成功')
            print(students)
            break
    else:
        print('你输入的姓名不存在')


def search_student():
    global students
    name = input('请输入你所要查找的姓名')
    for i in students:
        if i['name'] == name:
            print(i)
            break
    else:
        print('你输入的学员不存在')

def bl_student():
    global students
    for i in students:
        print(i)


print('-'*20)
print('欢迎来到学生管理系统')
print('1.添加学生的信息')
print('2,删除学生的信息')
print('3,修改学生的信息')
print('4,查询学生的信息')
print('5,遍历所有学生的信息')
print('6,退出系统')
print('-'*20)
while True:
    num = int(input('请输入所要执行的功能模块'))
    if num==1:
        add_student()
    elif num==2:
        del_student()
    elif num==3:
        replace_student()
    elif num==4:
        search_student()
    elif num==5:
        bl_student()
    elif num==6:
        print('感谢你的使用')
        break
    else:
        print('输入错误,请重新输入')
5.问题总结

在程序设计时,students[]用于存储多个学生信息,然后通过字典student[]存储单个学生的信息,将字典保存于列表中,学会运用globa关键字,然后就是break的巧妙利用,达到好的效果。

obal students
    for i in students:
        print(i)


print('-'*20)
print('欢迎来到学生管理系统')
print('1.添加学生的信息')
print('2,删除学生的信息')
print('3,修改学生的信息')
print('4,查询学生的信息')
print('5,遍历所有学生的信息')
print('6,退出系统')
print('-'*20)
while True:
    num = int(input('请输入所要执行的功能模块'))
    if num==1:
        add_student()
    elif num==2:
        del_student()
    elif num==3:
        replace_student()
    elif num==4:
        search_student()
    elif num==5:
        bl_student()
    elif num==6:
        print('感谢你的使用')
        break
    else:
        print('输入错误,请重新输入')
        
##### 5.==问题总结==
在程序设计时,students[]用于存储多个学生信息,然后通过字典student[]存储单个学生的信息,将字典保存于列表中,学会运用globa关键字,然后就是break的巧妙利用,达到好的效果。
;