网站软文标题,生态农业网站建设方案,揭阳企业自助建站系统,广州市网站建设企业一、函数基础
1.1、函数的用法和底层分析 函数是可重用的程序代码块。 函数的作用#xff0c;不仅可以实现代码的复用#xff0c;更能实现代码的一致性。一致性指的是#xff0c;只要修改函数的代码#xff0c;则所有调用该函数的地方都能得到体现。 在编写函数时#xf…
一、函数基础
1.1、函数的用法和底层分析 函数是可重用的程序代码块。 函数的作用不仅可以实现代码的复用更能实现代码的一致性。一致性指的是只要修改函数的代码则所有调用该函数的地方都能得到体现。 在编写函数时函数体中的代码写法和我们前面讲述的基本一致只是对代码实现了封装并增加了函数调用、传递参数、返回计算结果等内容。 1.2、函数简介
1.2.1函数的基本概念 一个程序由一个一个的任务组成函数就是代表一个任务或者一个功能(function)。 函数是代码复用的通用机制 1.2.2、函数的分类 内置函数 我们前面使用的str()、list()、len()等这些都是内置函数我们可以拿来直接使用。 标准库函数 我们可以通过import语句导入库然后使用其中定义的函数 第三方库函数 Python社区也提供了很多高质量的库。下载安装这些库后也是通过import语句导入然后可以使用这些第三方库的函数 用户自定义函数 用户自己定义的函数显然也是开发中适应用户自身需求定义的函数。今天我们学习的就是如何自定义函数。 1.2.3、 函数的定义和调用 实现某个功能的一段完整的代码code. 使用函数名称进行封装.以便 通过函数名调用,实现一次编写,多次调用的目的. python语言中封装函数尽量做到 高内聚 低耦合 (只完成自己的 功能, 函数执行成功与失败,与别的内容无关) 自定义函数语法 def 函数名(形式参数列表): code # 函数体 return value def add(a,b,c):# 执行三个数相加,并返回和sumabcprint(f{a} {b} {c}三个数相加的和为:{sum})return sum
add(10,20,30) 我们使用def来定义函数然后就是一个空格和函数名称 Python执行def时会创建一个函数对象并绑定到函数名变量上。参数列表 圆括号内是形式参数列表有多个参数则使用逗号隔开 定义时的形式参数不需要声明类型也不需要指定函数返回值类型 调用时的实际参数必须与形参列表一一对应return返回值 如果函数体中包含return语句则结束函数执行并返回值 如果函数体中不包含return语句则返回None值。调用函数之前必须要先定义函数即先调用def创建函数对象 内置函数对象会自动创建 标准库和第三方库函数通过import导入模块时会执行模块中的def语句 二、形参和实参 形参和实参的要点 圆括号内是形式参数列表有多个参数则使用逗号隔开定义时的形式参数不需要声明类型也不需要指定函数返回值类型调用时的实际参数必须与形参列表一一对应 def add(a, b): # a 和 b 是形参 return a b result add(5, 3) # 5 和 3 是实参
print(result) # 输出结果是 8
2.1、形参 定义形参是函数定义时声明的变量它们用来接收调用函数时传入的值。形参在函数内部使用作用域是函数内部。 特点 形参在函数定义时定义通常是在函数头部括号内。 形参可以被视为占位符用于代表将来的实际输入数据。 2.2、实参 定义实参是调用函数时传入的实际值或变量。实参可以是字面量、变量、表达式、以及其他函数的返回值等。 特点 实参是在函数调用时提供的实际传递给函数的值。 实参的类型和数量需要和形参匹配。 三、函数的参数传递
3.1、位置参数 位置参数是最基本的参数传递方式函数调用时参数的传递顺序必须与函数定义时的参数顺序一致 # 定义一个函数
def function(name, age, sex): # 需要传递三个参数print(f姓名: {name}, 年龄:{age}, 性别: {sex})# 调用这个函数
function(懒洋洋, 5, Man)#姓名: 懒洋洋, 年龄:5, 性别: Man
3.2、关键字参数 关键字参数允许在调用函数时使用参数名来传递参数这样可以不必考虑参数的顺序 # 定义一个函数 info: 做一个自我介绍
def info(name, age, score):print(fmy name is {name}, age: {age}, score: {score})# 使用关键字去调用info 函数
info(age18, score100, name小白)#my name is 小白, age: 18, score: 100
info(小白,score90, age6) # my name is 小白, age: 6, score: 90
3.3、缺省参数 缺省参数允许在定义函数时为某些参数提供默认值。如果在调用函数时没有提供这些参数的值则使用默认值 # 定义一个函数 info: 做一个自我介绍
def info(name某某某, age18, score100):print(fmy name is {name}, age: {age}, score: {score})# 调用info函数
info() # info函数在调用的时候没有给出参数,则name,age, score使用的是默认值
info(小白) # 小白给出的是位置参数name的内容, age,score使用的是默认值
info(age5, score20) # age score是关键字参数 name是没有给出值得.# name使用的是默认值参数info(小黑, age10) # name是位置参数,age是关键字参数score:默认值
info(age18,小白,score20) # error :一旦使用了关键字参数,后面的内容就能再是# 位置参数了。
3.4、不定长参数 不定长参数允许在调用函数时传递任意数量的位置参数和关键字参数。这种参数在函数定义时使用 *args 和 **kwargs 3.4.1、*args 不定长位置参数使用 *args 接收多个位置参数参数以元组的形式传递 def info(name, age, *hobby): # hobby参数前面有一个*表示的是不定长参数。print(fname:{name}, age: {age})print(fhobby : {hobby})# hobby这个参数是一个元组print(f{type(hobby)})# 调用函数info # 小白 与 5 是位置参数,会给到name,age
# 足球, 篮球, 保龄球 属于不定长参数,打包成元组,给到 hobby这个变量
info(小白, 5, 足球, 篮球, 保龄球)
# name:小白, age: 5
# hobby : (足球, 篮球, 保龄球)
# class tuple
print(**20)
info(小黑,10, 唱, 跳, 舞, 吃, 喝)
# name:小黑, age: 10
# hobby : (唱, 跳, 舞, 吃, 喝)
# class tuple
3.4.2、 **kwargs 不定长关键字参数使用 **kwargs 接收多个关键字参数参数以字典的形式传递 def info(name, age, **parent): # parent:不定长参数 前面有**,会将键值对的# 形式的参数打包成字典print(fname: {name}, age: {age})print(fparent: {parent})print(fparent: {type(parent)})# 调用info函数
info(小白, 5, mother母亲, father父亲)
# name: 小白, age: 5
# parent: {mother: 母亲, father: 父亲}
# parent: class dict
3.4.3、组合
def info(name, age, *hobby, **parent):print(fname:{name}, age: {age}, hobby: {hobby}, parent:{parent})print(f{type(hobby)})print(f{type(parent)})# 调用info函数
info(小白, 5, 唱,跳, 篮球, mother母亲, father父亲)name:小白, age: 5, hobby: (唱, 跳, 篮球), parent:{mother: 母亲, father: 父亲}
class tuple
class dict
# error,在* 与 **混用的时候,一旦使用了**传递键值对儿的时候,就不能再传递单个的参数了。
# info(小黑, 5, 唱, mother母亲, father父亲, 跳, 篮球)
四、函数的返回值 return返回值要点 如果函数体中包含return语句则结束函数执行并返回值 如果函数体中不包含return语句则返回None值 要返回多个值使用列表、元组、字典、集合将多个值“存起来”即可 返回多个值,会将返回值的值打包成 一个元组。 定义一个函数,返回100 ~ 999之间的所有的水仙花数字。 水仙数数字有 4个 def flower():# 定义一个列表,记录水仙花数字ls []# 编写功能,找到这四个水仙花数字for number in range(100, 1000):g number % 10s (number // 10) % 10b number // 100# 判断是不是水仙花数字if number g**3 s**3 b**3:ls.append(number)# 出了循环以后,ls里面的内容就是4个水仙花数字a, b, c, d ls[0], ls[1], ls[2], ls[3]return a, b, c, d# 接收函数的返回值
value1, value2, value3, value4 flower()
print(f{value1}, {value2}, {value3}, {value4})#153, 370, 371, 407result flower()
print(fresult : {result})#result : (153, 370, 371, 407)五、全局变量和局部变量
5.1、全局变量 在函数和类定义之外声明的变量。作用域为定义的模块从定义位置开始直到模块结束。 全局变量降低了函数的通用性和可读性。应尽量避免全局变量的使用。 global关键字作用: 声明使用的变量属于全局变量 global一般在函数的内部使用。 a 100 #全局变量
def f1():global a #如果要在函数内改变全局变量的值增加global关键字声明print(a) #打印全局变量a的值 a 300 f1()#100
f1()#300
print(a)#300
5.2、局部变量 在函数体中包含形式参数声明的变量。 局部变量的引用比全局变量快优先考虑使用 如果局部变量和全局变量同名则在函数内隐藏全局变量只使用同名的局部变量 a100
def f1():a 3 #同名的局部变量print(a)f1()#3
print(a) #a仍然是100没有变化5.3、局部变量和全局变量效率测试 局部变量的查询和访问速度比全局变量快优先考虑使用尤其是在循环的时候。 在特别强调效率的地方或者循环次数较多的地方可以通过将全局变量转为局部变量提高运行速度。 import time
a 1000
def test01():start time.time()global afor i in range(100000000):a 1end time.time()print(耗时{0}.format((end-start)))
def test02():c 1000start time.time()for i in range(100000000):c 1end time.time()print(耗时{0}.format((end-start)))
test01()#耗时6.526300430297852
test02()#耗时5.019754648208618
print(globals())5.4、nonlocal和global关键字 nonlocal 用来在内部函数中声明外层的局部变量。 global 函数内声明全局变量然后才使用全局变量 #测试nonlocal、global关键字的用法
a 100
def outer():b 10def inner():nonlocal b #声明外部函数的局部变量print(inner b:,b)#inner b: 10b 20global a #声明全局变量a 1000inner()print(outer b:,b)#outer b: 20
outer()
print(a:,a)#a 1000
六、lambda表达式和匿名函数 lambda表达式可以用来声明匿名函数。lambda函数是一种简单的、在同一行中定义函数的方法。lambda函数实际生成了一个函数对象。 lambda表达式只允许包含一个表达式不能包含复杂语句该表达式的计算结果就是函数的返回值。 lambda表达式的基本语法如下 lambda arg1,arg2,arg3... : 表达式 arg1 arg2 arg3为函数的参数。表达式相当于函数体。运算结果是表达式的运算结果。 七、嵌套函数 嵌套函数在函数内部定义的函数 def outer():print(outer)def inner():print(inner)inner()outer()inner()就是定义在outer()函数内部的函数。inner()的定义和调用都在outer()函数内部 应用场景 封装 - 数据隐藏 外部无法访问“嵌套函数”。 贯彻 DRY(Don’t Repeat Yourself) 原则 嵌套函数可以让我们在函数内部避免重复代码。 闭包 八、递归函数 递归(recursion)是一种常见的算法思路在很多算法中都会用到。比如深度优先搜索DFS:Depth First Search等。 递归的基本思想就是“自己调用自己” 递归函数指的是自己调用自己的函数在函数体内部直接或间接的自己调用自己。每个递归函数必须包含两个部分 终止条件 表示递归什么时候结束。一般用于返回值不再调用自己。 递归步骤 把第n步的值和第n-1步相关联。 ⚠️递归函数由于会创建大量的函数对象、过量的消耗内存和运算能力。在处理大量数据时谨慎使用。 使用递归函数计算一个数字的阶乘 n5
def jiec(n):if n1:return 1return n*jiec(n-1)
print(jiec(5))#120 九、eval()函数 功能将字符串str当成有效的表达式来求值并返回计算结果。 语法eval(expression, globalsNone, localsNone) 参数 source一个Python表达式或函数compile()返回的代码对象 globals可选。必须是dictionary locals可选。任意映射对象 result eval(2 3)
print(result) # 输出: 5x 10
result eval(x * 2)
print(result) # 输出: 20result eval(max(5, 10, 15) min(1, 2, 3))
print(result) # 输出: 16x 1
def my_func(): y 2 # 使用eval执行局部变量 return eval(x y, globals(), locals()) print(my_func()) # 输出: 3 ⚠️⚠️⚠️eval函数会将字符串当做语句来执行因此会被注入安全隐患。比如字符串中含有删除文件的语句。那就麻烦大了。因此使用时候要慎重 安全性使用 eval() 可能存在安全风险因为它会执行字符串中的任何 Python 代码。如果字符串来自不可信的来源如用户输入这可能导致代码注入风险。因此在处理不安全的输入时尽量避免使用 eval()。 性能eval() 的执行效率相对较低因为它会运行解析和执行极有可能在性能敏感的场合造成瓶颈。 替代方案对于简单的数学表达式可以使用 ast.literal_eval()它安全地求值字面量表达式如字典、列表、元组等不会执行其他代码。 import ast str_expr [1, 2, 3, 4]
result ast.literal_eval(str_expr) # 安全地转换字符串为列表
print(result) # 输出: [1, 2, 3, 4]
十、LEGB规则 Local 指的就是函数或者类的方法内部 Enclosed 指的是嵌套函数一个函数包裹另一个函数闭包 Global 指的是模块中的全局变量 Built in 指的是Python为自己保留的特殊名称 如果某个name映射在局部local命名空间中没有找到接下来就会在闭包作用域enclosed进行搜索如果闭包作用域也没有找到Python就会到全局global命名空间中进行查找最后会在内建built-in命名空间搜索 如果一个名称在所有命名空间中都没有找到就会产生一个NameError #测试LEGB
s global
def outer():s outerdef inner():s innerprint(s)inner()
outer()#inner十一、学生管理系统基于函数
# 完成学生管理系统# 1.创建一个班级信息: 班级使用列表这个容器进行表示
class_info []# 2. 定义一个python菜单函数
def print_menu():print(****************************)print(** 1. 增加学生 2. 删除学生 **)print(** 3. 修改学生 4. 查询学生 **)print(** 5. 显示所有学生信息 **)print(** 6. 退出学生管理系统 **)print(****************************)# 定义一个增加学生信息的函数
def add_student():student 使用字典数据类型进行描述;{name: name,age : age,score : score}# 声明使用的是全局变量global class_info# 从键盘中输入学生的信息name input(please input student name : )age int(input(please input student age : ))score int(input(please input student score : ))# 需要对学生的信息进行验证# 对名字进行重名认证,如果重复名字了,就不让在添加信息# class_info [{name:name, age:age, score:score}, {},{}]# 使用for循环进行遍历for info in class_info:# 如果class_info里面有数据,则info是学生的个人信息if info[name] name:print(您输入的学生已经存在,添加学生失败)return -1# 对年龄判断if 0 age 100:print(您输入的年龄有误,添加学生失败)return -2# 对成绩的判断if 0 score 100:print(您输入的成绩有误,添加学生失败)return -3# 通过输入的信息组建成一个字典student {name: name, age: age, score: score}# 将学生信息加入到列表当中class_info.append(student)print(f添加学生{name}信息成功)return 0# 删除学生
def remove_student(): 删除学生信息 # 1.global声明全局变量 class_infoglobal class_info# 2.根据学生姓名删除学生信息name input(please input remove student name : )# 3.根据学生的姓名找到需要删除的学生for student in class_info:if student[name] name:# 通过姓名找到了需要删除的学生 python 语言中列表可以根据值删除 remove ret input(f您确定要删除{name}的信息吗?如果确认请输入yes or y)if ret yes or ret y:class_info.remove(student)print(删除成功)return 0else:print(您的输入有误)return -1# for 循环结束, 代表了没有找到需要删除的学生print(您输入的学生不存在)return -2# 修改学生信息函数
def modify_student(): 修改学生信息 # 声明使用全局变量global class_info# 通过学生的学号对学生的信息进行修改: 列表将其下标当做学号number int(input(please input student number ))# 判断学号是否正确if len(class_info) number 0:print(您输入的学号有误)return -1# 根据学号修改相应的信息class_info[number][name] input(请输入修改之后的学生姓名: )class_info[number][age] int(input(请输入修改之后的学生年龄 :))class_info[number][score] int(input(请输入修改之后的学生成绩 ))print(修改学生成功)return 0# 定义一个查找学生的函数
def find_student():# 声明使用的变量是全局变量global class_info# 通过姓名查找学生的信息name input(please input student name : )for info in class_info:if info[name] name:print(f姓名: {info[name]}, age: {info[age]}, score:{info[score]})return 0print(您输入的学生不存在)return -1# 显示所有的学生信息
def show_student():# 声明使用的是全局变量global class_infofor info in class_info:print(f姓名: {info[name]}, age: {info[age]}, score:{info[score]})def main(): 学生管理系统主程序 # 死循环管理学生系统while True:# 打印学生管理系统菜单print_menu()# 给出提示信息,让用户选择自己的操作choose int(input(please input your choose))match choose:case 1:add_student()case 2:remove_student()case 3:modify_student()case 4:find_student()case 5:show_student()case 6:print(bye~)breakcase _:print(您的输入有误,请重新输入)pass# 调用main函数执行程序
main()
十二、思维导图