【Python深入浅出】解锁Python3自定义函数:从新手到高手的进阶之路

embedded/2025/2/5 12:35:21/

目录

  • 一、Python3 自定义函数初相识
  • 二、自定义函数的语法基础
    • (一)定义函数的基本格式
    • (二)函数命名规则
    • (三)参数与参数传递
    • (四)参数解包
  • 三、函数的返回值
    • (一)返回单一值
    • (二)返回多个值
    • (三)无返回值的函数
  • 四、函数的嵌套与作用域
    • (一)函数的嵌套定义
    • (二)作用域与命名空间
    • (三)global 关键字的使用
  • 五、实际应用案例
    • (一)数学计算类函数
    • (二)数据处理类函数
    • (三)文件操作类函数
  • 六、总结与展望
    • (一)回顾重点内容
    • (二)未来学习方向


一、Python3 自定义函数初相识

在 Python3 的编程世界里,函数是一种极为重要的概念。简单来说,函数就是组织好的、可重复使用的代码段 ,专门用于实现单一或相关联的功能。打个比方,你可以把函数想象成一个 “功能盒子”,只要往里面输入特定的数据(参数),它就能按照设定好的规则进行处理,然后输出相应的结果。

函数的存在有着诸多重要意义,它极大地提高了应用的模块性,使代码结构更加清晰、有条理。通过将复杂的任务分解为一个个独立的函数,每个函数专注于完成一项特定的功能,这样在编写和维护代码时就会更加轻松。例如,在开发一个电商系统时,可以将用户登录、商品查询、订单处理等功能分别封装成不同的函数,每个函数负责自己的业务逻辑,相互之间既独立又协作,使得整个系统的架构更加清晰,易于扩展和维护。

函数还能显著提高代码的重复利用率。当我们在程序中多次需要执行相同或相似的操作时,无需重复编写相同的代码,只需调用已定义好的函数即可。这不仅减少了代码量,降低了出错的概率,还提高了开发效率。例如,在一个数据分析项目中,可能需要多次对数据进行清洗和预处理操作,我们可以将这些操作封装成一个函数,每次需要处理数据时,直接调用该函数,而不需要重新编写数据清洗的代码。

二、自定义函数的语法基础

(一)定义函数的基本格式

在 Python3 中,使用def关键字来定义函数 ,其基本语法结构如下:

python">def 函数名(参数列表):函数体return 返回值
  • def:这是 Python 中定义函数的关键字,表明接下来要定义一个函数。
  • 函数名:是你为这个函数取的名字,遵循 Python 的命名规则,要具有描述性,能清晰地反映函数的功能。例如,计算两个数之和的函数可以命名为add_numbers。
  • 参数列表:位于函数名后的括号内,用于接收调用函数时传入的参数。参数可以有多个,参数之间用逗号隔开;也可以没有参数,此时括号为空。比如,定义一个计算圆面积的函数,可能需要接收圆的半径作为参数,那么参数列表中就可以写radius。
  • 函数体:是函数实现具体功能的代码块,这部分代码需要缩进,通常使用 4 个空格或一个制表符来表示缩进。在函数体中,你可以编写各种语句来实现函数的功能,比如进行数据处理、调用其他函数等。例如,在计算圆面积的函数体中,会根据半径计算圆的面积。
  • return语句:用于结束函数的执行,并返回一个值给调用者。return语句是可选的,如果函数没有return语句,或者return语句后面没有表达式,函数将返回None。例如,在计算圆面积的函数中,return语句会返回计算得到的圆面积。

下面通过一个简单的示例来展示函数的定义:

python">def greet(name):"""该函数用于向指定的人打招呼:param name: 要打招呼的人的名字:return: 打招呼的语句"""message = f"Hello, {name}!"return message# 调用函数
result = greet("Alice")
print(result)

在上述示例中,greet函数接受一个参数name,函数体中创建了一个包含问候语的字符串message,最后通过return语句返回这个字符串。调用greet函数时,传入参数"Alice",函数返回"Hello, Alice!",并将其赋值给变量result,最后打印出结果。

(二)函数命名规则

函数命名在 Python 编程中至关重要,它不仅影响代码的可读性,还关系到团队协作和项目的维护。在 Python3 中,函数命名需要遵循一系列规则,以确保代码的规范性和可理解性。

字符组成:函数名只能包含字母、数字和下划线(_)。例如,calculate_sum、count123、print_result等都是符合规则的函数名。而像my - function(包含连字符)、$price(包含美元符号)这样的命名则是不允许的。

首字符限制:函数名不能以数字开头。例如,123_function是错误的命名,而function123则是正确的。这是因为 Python 解释器在解析代码时,需要明确区分函数名和其他语法元素,如果函数名以数字开头,可能会导致混淆。

避免关键字冲突:函数名不能是 Python 的关键字或内置函数名。Python 有一系列保留关键字,如if、else、while、for等,这些关键字在 Python 语法中有特定的含义,不能用作函数名。同时,也应避免使用内置函数名,如print、len、sum等,虽然在某些情况下可以覆盖内置函数,但这会导致代码的行为与预期不符,增加调试的难度。例如,如果你将一个函数命名为print,并在后续代码中调用print,可能无法实现原本的打印功能,而是调用了你自定义的函数,从而引发错误。

具有描述性:为了让代码更易读和维护,函数名应该具有描述性,能够准确地反映函数的功能。例如,一个用于计算两个数乘积的函数,命名为multiply_numbers就比命名为func更能让人直观地理解其用途。这样,当其他开发者阅读代码时,能够快速明白函数的作用,无需查看函数内部的实现细节。在一个复杂的项目中,清晰的函数命名可以大大提高代码的可维护性,减少沟通成本。

(三)参数与参数传递

1.位置参数:位置参数是最常见的参数传递方式。在定义函数时,按照顺序依次列出参数,调用函数时,也必须按照相同的顺序传递参数。例如:

python">def add_numbers(a, b):return a + bresult = add_numbers(3, 5)
print(result)

在这个例子中,add_numbers函数接受两个位置参数a和b。调用函数时,3被传递给a,5被传递给b,函数返回它们的和8。如果参数顺序错误,比如写成add_numbers(5, 3),虽然结果相同,但在逻辑上与函数定义的初衷不符,并且在更复杂的函数中,可能会导致严重的错误。

2.关键字参数:关键字参数通过指定参数名称来传递值,这样可以打破参数的位置顺序限制,提高代码的可读性。例如:

python">def greet(name, message):return f"{message}, {name}!"result = greet(message="Hello", name="Alice")
print(result)

在greet函数中,我们使用关键字参数调用,message被赋值为"Hello",name被赋值为"Alice"。即使参数顺序与定义时不同,也能正确传递参数值,输出"Hello, Alice!"。这种方式在参数较多时尤为有用,能让代码更清晰地表达每个参数的含义。

3.默认参数:默认参数是在定义函数时为参数指定一个默认值。调用函数时,如果没有传递该参数的值,就会使用默认值。例如:

python">def greet(name, message="Hello"):return f"{message}, {name}!"result1 = greet("Alice")
result2 = greet("Bob", "Hi")
print(result1)
print(result2)

在greet函数中,message是默认参数,默认值为"Hello"。当调用greet(“Alice”)时,由于没有传递message参数,所以使用默认值"Hello",输出"Hello, Alice!“;当调用greet(“Bob”, “Hi”)时,传递了message参数为"Hi”,则使用传入的值,输出"Hi, Bob!"。需要注意的是,默认参数必须指向不可变对象,如字符串、数字、元组等。如果默认参数是可变对象(如列表、字典),可能会导致意外的结果。例如:

python">def append_to_list(value, my_list=[]):my_list.append(value)return my_listlist1 = append_to_list(1)
list2 = append_to_list(2)
print(list1)
print(list2)

在这个例子中,my_list是可变对象,每次调用函数时,如果不传入my_list参数,都会使用同一个默认的空列表。所以list1和list2实际上是同一个列表,结果会是[1, 2]和[1, 2],而不是预期的[1]和[2]。为了避免这种情况,可以将默认值设为None,在函数内部再创建可变对象:

python">def append_to_list(value, my_list=None):if my_list is None:my_list = []my_list.append(value)return my_listlist1 = append_to_list(1)
list2 = append_to_list(2)
print(list1)
print(list2)

这样,每次调用函数时,如果my_list为None,就会创建一个新的空列表,list1和list2就会是独立的列表,结果为[1]和[2]。
4.可变参数
*args可变位置参数:*args用于接收任意数量的位置参数,这些参数会被收集成一个元组。在函数内部,可以像操作元组一样操作*args。例如:

python">def calculate_sum(*args):total = 0for num in args:total += numreturn totalresult = calculate_sum(1, 2, 3, 4, 5)
print(result)

在calculate_sum函数中,*args可以接收任意多个位置参数。调用函数时,传入的1, 2, 3, 4, 5被收集成元组(1, 2, 3, 4, 5),函数内部通过循环累加这些参数,最终返回它们的和15。

**kwargs可变关键字参数:**kwargs用于接收任意数量的关键字参数,这些参数会被收集成一个字典。在函数内部,可以通过键值对的方式访问**kwargs中的参数。例如:

python">def print_info(**kwargs):for key, value in kwargs.items():print(f"{key}: {value}")print_info(name="Alice", age=25, city="New York")

在print_info函数中,**kwargs可以接收任意多个关键字参数。调用函数时,传入的name=“Alice”, age=25, city="New York"被收集成字典{‘name’: ‘Alice’, ‘age’: 25, ‘city’: ‘New York’},函数内部通过循环遍历字典,打印出每个键值对。

5.参数混合使用:在一个函数中,可以同时使用位置参数、默认参数、*args和**kwargs,但要遵循一定的顺序。一般来说,顺序为:位置参数、默认参数、*args、**kwargs。例如:

python">def show_info(name, age=18, *hobbies, **other_info):print(f"Name: {name}, Age: {age}")print("Hobbies:")for hobby in hobbies:print(f"- {hobby}")print("Other Information:")for key, value in other_info.items():print(f"{key}: {value}")show_info("Alice", 20, "Reading", "Painting", city="New York", job="Engineer")

在show_info函数中,name是位置参数,age是默认参数,*hobbies收集可变位置参数,**other_info收集可变关键字参数。调用函数时,先传入位置参数"Alice",然后传入默认参数20(覆盖默认值18),接着传入可变位置参数"Reading"和"Painting",最后传入可变关键字参数city="New York"和job=“Engineer”。函数会按照顺序依次处理这些参数,输出相应的信息。

(四)参数解包

1.解包位置参数:在调用函数时,可以使用*运算符对元组或列表进行解包,将其中的元素作为位置参数传递给函数。例如:

python">def add_numbers(a, b, c):return a + b + cnums = (1, 2, 3)
result = add_numbers(*nums)
print(result)

在这个例子中,nums是一个元组,通过nums将元组解包,1、2、3分别作为位置参数传递给add_numbers函数,函数返回它们的和6。同样,对于列表也可以使用运算符进行解包:

python">nums_list = [1, 2, 3]
result = add_numbers(*nums_list)
print(result)

这里将列表nums_list解包后传递给函数,结果也是6。
2.解包关键字参数:使用**运算符可以对字典进行解包,将字典中的键值对作为关键字参数传递给函数。例如:

python">def greet(name, message):return f"{message}, {name}!"info = {"name": "Alice", "message": "Hello"}
result = greet(**info)
print(result)

在greet函数调用中,info是一个字典,通过**info将字典解包,“name”: “Alice"和"message”: “Hello"作为关键字参数传递给函数,函数返回"Hello, Alice!”。解包关键字参数时,字典的键必须与函数参数名匹配,否则会报错。例如,如果字典中存在函数参数名之外的键,或者缺少函数所需的参数键,都会导致运行时错误。

三、函数的返回值

(一)返回单一值

在 Python 函数中,return关键字用于返回一个值给调用者,这个返回值可以是任何数据类型,包括整数、浮点数、字符串、列表、字典等。当函数执行到return语句时,函数将会立即结束,并将return后面的表达式的值返回给调用者。例如:

python">def add_numbers(a, b):result = a + breturn resultsum_result = add_numbers(3, 5)
print(sum_result)

在上述代码中,add_numbers函数接收两个参数a和b,将它们相加的结果存储在result变量中,然后通过return语句返回result的值。调用add_numbers函数时,传入3和5作为参数,函数返回8,并将其赋值给sum_result变量,最后打印出8。

需要注意的是,return语句的作用不仅仅是返回一个值,它还会结束函数的执行。也就是说,一旦函数执行到return语句,函数体内return语句后面的代码将不会被执行。例如:

python">def print_and_return():print("这是在return语句之前的打印")return 10print("这是在return语句之后的打印,不会被执行")value = print_and_return()
print(value)

在这个例子中,print_and_return函数先打印出 “这是在 return 语句之前的打印”,然后执行return 10语句,函数结束,后面的 “这是在 return 语句之后的打印,不会被执行” 不会被打印出来。最后,return返回的10被赋值给value变量并打印。

(二)返回多个值

在 Python 中,函数可以返回多个值。实际上,当函数返回多个值时,这些值会被封装成一个元组(tuple)返回。元组是一种有序的、不可变的数据类型,可以容纳多个值。例如:

python">def calculate(a, b):sum_result = a + bdifference = a - bproduct = a * bquotient = a / b if b!= 0 else Nonereturn sum_result, difference, product, quotientresult = calculate(10, 5)
print(result)

在上述代码中,calculate函数接收两个参数a和b,分别计算它们的和、差、积、商,然后通过return语句返回这四个结果。调用calculate函数时,传入10和5作为参数,函数返回一个元组(15, 5, 50, 2.0),并将其赋值给result变量,最后打印出这个元组。

当函数返回一个元组时,我们可以使用解包(unpacking)的方式将元组中的值赋给多个变量。例如:

python">sum_result, difference, product, quotient = calculate(10, 5)
print(f"和: {sum_result}")
print(f"差: {difference}")
print(f"积: {product}")
print(f"商: {quotient}")

在这个例子中,通过解包操作,将calculate函数返回的元组中的四个值分别赋给sum_result、difference、product和quotient四个变量,然后分别打印出这些变量的值。

(三)无返回值的函数

有些函数执行特定的操作,但不需要返回值。在 Python 中,这样的函数实际上会返回None,None是 Python 中的一个特殊字面量,表示空的、无实际意义的值。对于无返回值的函数,return语句可以省略不写,或者使用return语句但不跟任何表达式。例如:

python">def print_hello():print("Hello, World!")result1 = print_hello()
print(result1)

在上述代码中,print_hello函数的功能是打印 “Hello, World!”,它没有返回值,所以return语句被省略。调用print_hello函数时,函数执行打印操作后结束,返回None,将其赋值给result1变量,最后打印出None。
再看一个使用return但不跟表达式的例子:

python">def greet(name):if name:print(f"Hello, {name}!")else:returnresult2 = greet("Alice")
print(result2)
result3 = greet("")
print(result3)

在greet函数中,当name不为空时,打印问候语;当name为空时,使用return语句返回None。调用greet(“Alice”)时,函数打印问候语后结束,返回None;调用greet(“”)时,函数直接执行return语句返回None。最后分别打印出这两个返回值,均为None。在实际应用中,无返回值的函数常用于执行一些不需要返回结果的操作,如打印信息、修改全局变量、进行文件写入等。

四、函数的嵌套与作用域

(一)函数的嵌套定义

在 Python 中,函数的定义是非常灵活的,其中一个显著的特性就是允许在函数内部嵌套定义其他函数 。这种嵌套定义的方式,为我们编写更加复杂和模块化的代码提供了便利。例如:

python">def outer_function():print("这是外层函数")def inner_function():print("这是内层函数")inner_function()outer_function()

在上述代码中,outer_function是外层函数,在其内部定义了inner_function内层函数。当调用outer_function时,首先会打印 “这是外层函数”,然后在outer_function内部调用inner_function,进而打印 “这是内层函数”。

从作用域的角度来看,外层函数可以访问内层函数的定义,但不能直接访问内层函数内部的变量。而内层函数可以访问外层函数的变量,这是因为内层函数处于外层函数的作用域内,这种特性被称为词法作用域(Lexical Scoping)。例如:

python">def outer_function():outer_variable = 10def inner_function():print(f"内层函数访问外层函数的变量: {outer_variable}")inner_function()outer_function()

在这个例子中,outer_variable是外层函数outer_function的变量,内层函数inner_function可以访问并打印这个变量的值。然而,如果尝试在outer_function外部访问inner_function,会引发NameError错误,因为inner_function的作用域仅限于outer_function内部。同样,在内层函数中定义的变量,外层函数也无法直接访问。例如:

python">def outer_function():def inner_function():inner_variable = 20# 下面这行代码会报错,因为无法访问内层函数的变量print(inner_variable)outer_function()

上述代码中,inner_variable是inner_function内部定义的变量,outer_function无法访问它,所以会抛出NameError异常。

(二)作用域与命名空间

1.作用域:在 Python 中,作用域是指程序中可以直接访问命名空间的文本区域。简单来说,作用域决定了变量的可见性和生命周期。Python 主要有两种作用域:全局作用域和局部作用域。
全局作用域:定义在函数外部的变量具有全局作用域,这些变量可以在整个程序的任何地方被访问(除非在局部作用域中被同名变量遮蔽)。例如:

python">global_variable = 100def some_function():print(f"在函数内部访问全局变量: {global_variable}")some_function()
print(f"在函数外部访问全局变量: {global_variable}")

在上述代码中,global_variable是全局变量,在some_function内部和外部都可以被访问。
局部作用域:定义在函数内部的变量具有局部作用域,这些变量只能在函数内部被访问。当函数执行结束时,局部变量会被销毁,其占用的内存空间也会被释放。例如:

python">def some_function():local_variable = 20print(f"在函数内部访问局部变量: {local_variable}")some_function()
# 下面这行代码会报错,因为无法在函数外部访问局部变量
print(local_variable)

在这个例子中,local_variable是some_function函数内部的局部变量,在函数外部无法访问,所以最后一行代码会抛出NameError异常。

2.命名空间:命名空间是从名称到对象的映射,它提供了一种在程序中避免名字冲突的机制。不同的命名空间相互独立,同一个命名空间中不能有重名,但不同的命名空间可以有相同的名字,且不会相互影响。Python 中有三种主要的命名空间:

内置命名空间:这是 Python 解释器启动时就创建的命名空间,包含了 Python 内置的函数、异常和类型等,比如print、len、Exception等。内置命名空间的生命周期从 Python 解释器启动开始,到解释器退出时结束。

全局命名空间:模块中定义的名称会被放入全局命名空间,包括函数、类、模块级的变量和常量等。全局命名空间在模块被加载时创建,在 Python 解释器退出时销毁。例如,在一个 Python 脚本中定义的全局变量和函数都属于全局命名空间。

局部命名空间:函数中定义的名称会被放入局部命名空间,包括函数的参数和局部定义的变量等。局部命名空间在函数被调用时创建,在函数执行结束时销毁。例如,在函数内部定义的变量就属于局部命名空间。

命名空间的查找顺序是:当引用一个变量时,Python 会首先在局部命名空间中查找,如果找不到,就会到全局命名空间中查找,最后到内置命名空间中查找。如果在这三个命名空间中都找不到该变量,就会抛出NameError异常。例如:

python"># 全局变量
global_variable = 10def some_function():# 局部变量local_variable = 20print(local_variable)  # 首先在局部命名空间中找到local_variable,输出20print(global_variable)  # 在局部命名空间中找不到global_variable,到全局命名空间中找到,输出10# 这里没有与内置命名空间冲突的变量,所以不会涉及到内置命名空间的查找some_function()

(三)global 关键字的使用

在 Python 中,当我们在函数内部想要修改全局变量时,需要使用global关键字进行声明。如果不使用global关键字,而直接对全局变量进行赋值操作,Python 会认为我们是在创建一个同名的局部变量,而不是修改全局变量。例如:

python">global_variable = 10def some_function():# 这里没有使用global关键字,所以是创建一个新的局部变量global_variable = 20print(f"函数内部的global_variable: {global_variable}")some_function()
print(f"函数外部的global_variable: {global_variable}")

在上述代码中,some_function函数内部的global_variable = 20语句创建了一个新的局部变量global_variable,并将其赋值为 20,而函数外部的全局变量global_variable的值仍然是 10。输出结果为:

python">函数内部的global_variable: 20
函数外部的global_variable: 10

如果我们想要在函数内部修改全局变量的值,就需要使用global关键字声明。例如:

python">global_variable = 10def some_function():global global_variableglobal_variable = 20print(f"函数内部的global_variable: {global_variable}")some_function()
print(f"函数外部的global_variable: {global_variable}")

在这个例子中,global global_variable语句声明了在函数内部使用的global_variable是全局变量,而不是创建新的局部变量。因此,global_variable = 20语句会修改全局变量global_variable的值。输出结果为:

python">函数内部的global_variable: 20
函数外部的global_variable: 20

需要注意的是,如果在函数内部既想读取全局变量的值,又想修改它的值,也需要使用global关键字声明。例如:

python">global_variable = 10def some_function():# 这里必须使用global关键字声明,否则无法修改全局变量global global_variableprint(f"读取全局变量的值: {global_variable}")global_variable = global_variable + 10print(f"修改后的全局变量的值: {global_variable}")some_function()
print(f"函数外部的global_variable: {global_variable}")

上述代码中,通过global关键字声明后,函数内部既可以读取全局变量global_variable的值,也可以对其进行修改,最终函数外部的全局变量也会被成功修改。

五、实际应用案例

(一)数学计算类函数

在数学计算领域,自定义函数能极大地简化复杂的计算过程。以计算阶乘为例,阶乘是指从 1 到该数的所有正整数的乘积,在很多数学和统计学问题中都有应用。比如在排列组合问题中,计算从 n 个不同元素中取出 m 个元素的排列数,就需要用到阶乘的计算。在 Python 中,我们可以使用循环来实现计算阶乘的函数:

python">def factorial(n):result = 1for i in range(1, n + 1):result *= ireturn result# 计算5的阶乘
factorial_of_5 = factorial(5)
print(f"5的阶乘是: {factorial_of_5}")

上述代码定义了factorial函数,它接受一个整数n作为参数,通过循环从 1 到n依次累乘,最终返回n的阶乘。在计算 5 的阶乘时,函数会依次计算 1 * 2 * 3 * 4 * 5,得到结果 120。

再比如求两个数的最大公约数,最大公约数在分数化简、密码学等领域有着广泛的应用。例如在密码学中,一些加密算法需要用到互质的数,而判断两个数是否互质就需要计算它们的最大公约数。我们可以使用辗转相除法来实现这个函数:

python">def gcd(a, b):while b:a, b = b, a % breturn a# 计算18和24的最大公约数
greatest_common_divisor = gcd(18, 24)
print(f"18和24的最大公约数是: {greatest_common_divisor}")

在gcd函数中,使用while循环不断更新a和b的值,直到b为 0,此时a的值就是最大公约数。在计算 18 和 24 的最大公约数时,通过辗转相除,最终得到结果 6。

(二)数据处理类函数

在数据处理方面,自定义函数可以帮助我们高效地对数据进行各种操作。例如,对列表进行排序是数据分析和处理中常见的操作。假设有一个包含学生成绩的列表,我们想要按照成绩从高到低进行排序,以便快速了解学生的成绩排名情况。在 Python 中,我们可以使用内置的sorted函数结合自定义的排序规则来实现:

python">students = [{"name": "Alice", "score": 85},{"name": "Bob", "score": 78},{"name": "Charlie", "score": 92}
]def sort_students_by_score(students):return sorted(students, key=lambda student: student["score"], reverse=True)sorted_students = sort_students_by_score(students)
for student in sorted_students:print(f"{student['name']}: {student['score']}")

在上述代码中,sort_students_by_score函数使用sorted函数对students列表进行排序。key参数指定了排序的依据,这里使用lambda函数提取每个学生字典中的score值作为排序依据。reverse=True表示按降序排列。最终,输出的学生列表将按照成绩从高到低排列。

再比如,从列表中筛选特定元素也是常见的数据处理需求。假设我们有一个包含数字的列表,想要筛选出其中的偶数,用于后续的数据分析,比如统计偶数的数量、计算偶数的平均值等。我们可以使用列表推导式或filter函数来实现:

python">numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]def filter_even_numbers(numbers):return [num for num in numbers if num % 2 == 0]even_numbers = filter_even_numbers(numbers)
print(f"筛选出的偶数: {even_numbers}")

在filter_even_numbers函数中,使用列表推导式遍历numbers列表,通过条件num % 2 == 0筛选出其中的偶数,最终返回一个包含所有偶数的新列表。

(三)文件操作类函数

在文件操作中,自定义函数可以将复杂的文件读取、写入和关闭操作封装起来,使代码更加简洁和易维护。例如,在读取一个文本文件的内容时,我们可以定义一个函数来完成这个任务。假设我们有一个记录学生信息的文本文件,每行包含一个学生的姓名和成绩,我们需要读取这个文件并将学生信息存储在一个列表中,以便后续处理,比如统计平均成绩、找出成绩最高的学生等。代码如下:

python">def read_student_info(file_path):student_info = []with open(file_path, 'r', encoding='utf-8') as file:for line in file:name, score = line.strip().split(',')student_info.append({"name": name, "score": int(score)})return student_info# 读取学生信息文件
students = read_student_info('students.txt')
for student in students:print(student)

在read_student_info函数中,使用with open语句打开文件,以确保文件在使用后正确关闭。通过逐行读取文件内容,使用strip方法去除每行的首尾空白字符,再使用split方法以逗号为分隔符将每行内容拆分为姓名和成绩,最后将学生信息存储在字典中并添加到列表中返回。

对于写入文件操作,假设我们有一个包含学生信息的列表,需要将这些信息写入一个新的文本文件中,以便保存和共享数据。我们可以定义如下函数:

python">def write_student_info(file_path, students):with open(file_path, 'w', encoding='utf-8') as file:for student in students:file.write(f"{student['name']},{student['score']}\n")# 示例学生信息列表
students = [{"name": "Alice", "score": 85},{"name": "Bob", "score": 78}
]
# 写入学生信息到文件
write_student_info('new_students.txt', students)

在write_student_info函数中,同样使用with open语句打开文件,这次以写入模式打开。通过遍历学生信息列表,将每个学生的姓名和成绩按照指定格式写入文件,每行末尾添加换行符。这样,文件new_students.txt中就会保存学生的信息。

六、总结与展望

(一)回顾重点内容

在 Python3 的编程领域中,自定义函数是极为重要的基础内容。从语法基础来看,使用def关键字定义函数,函数名需遵循严格的命名规则,参数传递方式丰富多样,包括位置参数、关键字参数、默认参数、可变参数(*args和**kwargs),并且可以对参数进行解包操作,以更灵活地传递数据。

函数的返回值类型丰富,既可以返回单一值,涵盖各种数据类型;也能返回多个值,实际上是以元组形式返回;还有些函数无返回值,这类函数通常执行特定操作,如打印信息、修改全局变量等,最终返回None。

函数的嵌套与作用域也是关键知识点。函数可以嵌套定义,内层函数能访问外层函数的变量,但外层函数无法直接访问内层函数的变量。作用域分为全局作用域和局部作用域,分别对应全局变量和局部变量,命名空间则有内置命名空间、全局命名空间和局部命名空间,它们共同决定了变量的可见性和生命周期。当在函数内部需要修改全局变量时,需使用global关键字声明。

在实际应用中,自定义函数在数学计算、数据处理和文件操作等诸多领域都发挥着重要作用。通过定义各种功能的函数,能够显著提高代码的模块化程度和重复利用率,使代码更加简洁、易维护。

(二)未来学习方向

当你已经熟练掌握了 Python3 自定义函数的基础知识后,还有更多高级的函数特性等待你去探索。生成器和迭代器是 Python 中强大的工具,它们允许你在不占用大量内存的情况下处理大量数据。生成器通过yield关键字实现,能够按需生成数据,而不是一次性生成所有数据,这在处理大数据集时非常高效。迭代器则提供了一种统一的方式来遍历各种数据结构,无论是列表、字典还是自定义的数据类型。

装饰器也是 Python 函数的一个重要特性,它允许你在不修改函数代码的情况下,为函数添加额外的功能。比如,你可以使用装饰器来实现日志记录、性能测试、权限验证等功能。通过使用装饰器,你可以使代码更加简洁、可维护,并且提高代码的复用性。

继续深入学习这些高级函数特性,将极大地提升你的 Python 编程能力,让你能够更加高效地解决各种复杂的编程问题。


http://www.ppmy.cn/embedded/159749.html

相关文章

【C++】STL——vector的使用

目录 💕1.vector介绍 💕2.vector的基本用法 💕3.vector功能的具体用法 (讲解) 💕4.vector——size,capacity函数的使用 (简单略讲) 💕5.resize&#xff…

SpringBoot 整合 SpringMVC:配置嵌入式服务器

修改和 server 相关的配置(ServerProperties): server.port8081 server.context‐path/tx server.tomcat.uri‐encodingUTF‐8 注册 Servlet 三大组件:Servlet、Fileter、Listener SpringBoot 默认是以 jar 包的方式启动嵌入式的 Servlet 容器来启动 Spr…

python Flask-Redis 连接远程redis

当使用Flask-Redis连接远程Redis时,首先需要安装Flask-Redis库。可以通过以下命令进行安装: pip install Flask-Redis然后,你可以使用以下示例代码连接远程Redis: from flask import Flask from flask_redis import FlaskRedisa…

Machine Learning Engineering Open Book 机器学习工程开放书

文章目录 一、关于 Machine Learning Engineering Open Book二、书籍目录三、关键对照表四、快捷方式 一、关于 Machine Learning Engineering Open Book 这是一个开放的方法、工具和分步说明集合,有助于成功训练和微调大型语言模型和多模态模型及其推理。 这是一…

对比DeepSeek、ChatGPT和Kimi的学术写作中搜集参考文献能力

参考文献 列出引用过的文献,按引用顺序排列,并确保格式规范。只列举确实阅读过的文献,包括书籍、期刊文章等,以便读者进一步查阅相关资料。也可以利用endnotes和zotero等文献管理工具插入文献。由于ChatGPT4无法联网进行检索&…

深度解读 Docker Swarm

一、引言 随着业务规模的不断扩大和应用复杂度的增加,容器集群管理的需求应运而生。如何有效地管理和调度大量的容器,确保应用的高可用性、弹性伸缩和资源的合理分配,成为了亟待解决的问题。Docker Swarm 作为 Docker 官方推出的容器集群管理工具,正是在这样的背景下崭露头…

【Convex Optimization Stanford】Lec7. Statistical estimation

【Convex Optimization Stanford】Lec7. Statistical estimation 前言参数化分布估计带有独立同分布噪声的线性估计Logistic 回归二分假说检验 实验设计 前言 略 参数化分布估计 极大似然估计,大概意思就是调整参数,让 y y y出现的概率的对数值最大。…

部署keepalvied+lVS(dr)高可用集群

第一步,环境准备 服务器名称 IP 描述 master VIP:192.168.244.100 DIP:192.168.244.101 高可用keeplived_master LVS负载均衡 backup VIP:192.168.244.100 DIP:192.168.244.102 高可用keeplived_backup LVS负载均衡 server1 RIP:192.168.244.103 Web服务…