python中的函数与异常
所谓函数就是一个被命名的独立的,完成特定功能的代码段,并可能给调用它的程序一个返回值def 函数名称([参数1, 参数2, ...]):函数体...[return 返回值]当检测到一个错误时,解释器就无法继续执行了,反而出现了一些错误的提示,这就是所谓的"异常"。
python中的函数与异常
函数的作用与使用步骤
函数的作用
在python实际开发中,我们使用函数的目的只有一个"让我们的代码可以被重复的使用"
函数的作用:
- 代码重复使用
- 模块化编程 (模块化编程的核心就是函数,我们把一个系统的功能分化成若干个功能,每个功能就是一个函数)
编程可分为两大类:1.模块化编程 2.面向对象编程
函数的定义
所谓函数就是一个被命名的,独立的,完成特定功能的代码段,并可能给调用它的程序一个返回值
基本语法:
def 函数名称([参数1, 参数2, ...]):
函数体
...
[return 返回值]
函数的调用
先定义后使用
# 定义函数
def 函数名称([参数1, 参数2, ...]):
函数体
...
[return 返回值]
# 调用函数
函数名称(参数1, 参数2, ...)
引入函数案例
-
使用python,编写一个打招呼啊程序
# 遇见一个人say hello print('hello') # 遇见一个人say hello print('hello') # 遇见一个人say hello print('hello')为了避免程序的重复性,对以上代码进行进一步优化
-
编写一个函数,多次利用
# 定义函数 def say_hello(): print('hello') # 调用函数 # 遇见一个人say hello say_hello() # 遇见一个人say hello say_hello() # 遇见一个人say hello say_hello() -
再次对函数进行升级,以实现向不同的人打招呼
# 定义一个函数,同时为其定义一个参数 def say_hello(name): print(f'hello,{name}') # 调用函数 # hello Tina say_hello('Tina') # hello Jack say_hello('Jack') # hello Rose say_hello('Rose') -
函数设计原则为’高内聚,低耦合’,函数执行完毕后,应主动把数返回给调用处,而不应该都交由print()等函数直接输出
# 定义一个函数,拥有name参数,同时函数执行完毕后,拥有一个return返回值 def say_hello(name): # 执行一系列相关操作... return 'hello,' + name # 调用函数 # hello Tina print(say_hello('Tina')) # hello Jack print(say_hello('Jack')) # hello Rose print(say_hello('Rose'))
return返回值(拓展)
拓展1:
def return_num():
return 1
return 2
result = return_num()
print(result) # 1
以上述代码为例,函数在执行时,只执行了第一个return,是因为return可以退出当前函数,导致return下方的代码不执行
拓展2:
def return_num():
return 1, 2
result = return_num()
print(result) # (1, 2)
print(type(result)) # <class 'tuple'>
案例:求两个数的四则运算结果
def calculation(num1, num2):
summer = num1 + num2
diff = num1 - num2
mult = num1 * num2
quot = num1 / num2
return summer, diff, mult, quot
# 调用size方法
print(calculation(20, 5))
函数说明文档(拓展)
更方便的查看函数的作用:

用三引号, 添加函数注释
必须写到函数内部第一行, 可以增加可阅读性
函数的嵌套
函数的嵌套调用指的是一个函数里面又调用了另一个函数
基本语法:
def fun_b():
print('fun_b')
def fun_a():
print('fun_a')
fun_b()
print('fun_end')
fun_a()
"""
嵌套函数的执行流程:
1.代码遵循一个'顺序原则',从下往上,从左往后开始执行.代码执行到fun_b的定义,会在计算机内存中声明了一个fun_b函数,但内部代码并没有执行
2.继续执行到fun_a函数的定义,会在计算机内存中声明有一个fun_a函数,函数没有真正的调用,内部没有执行
3.代码继续向下,发现fun_a(),即代表调用了该函数并执行其内部函数,打印'fun_a'
4.继续执行,发现fun_b(),执行函数fun_b内部代码,打印'fun_b'
5.fun_b函数执行完后,最后打印出'fun_end'
"""
案例:
编写一个程序,求出一个列表中偶数和奇数的和,并以列表返回。
# 1. 定义函数 calculate_sum(),参数为一个数字列表 numbers_list
def calculate_sum():
# 2. 初始化偶数和为0
even_sum = 0
# 3. 初始化奇数和为0
odd_sum = 0
# 4. 遍历数字列表中的每个数字
for num in numbers_list:
# 5. 检查数字是否为偶数
if num % 2 == 0:
even_sum += num
else:
odd_sum += num
# 6. 返回一个列表,第一个元素为偶数的和,第二个元素为奇数的和
return [even_sum, odd_sum]
numbers = [2, 5, 7, 4, 8, 9]
# 调用函数,并获取结果
result = calculate_sum(numbers)
print(f"偶数的和是: {result[0]}, 奇数的和是: {result[1]}")
变量的作用域(了解)
变量的作用域值得是变量的作用范围(变量在哪里可以用,在哪里不可以用),主要分为两类:全局作用域与局部作用域
其作用域的划分也比较简单,在函数内部定义范围就称之为局部作用域,在函数外部(全局)定义范围就是全局作用域
# 全局作用域
def func():
# 局部作用域
局部变量与全局变量
在python中,定义在函数外部的变量就称之为全局变量;定义在函数内部的变量就称之为局部变量
# 定义在函数外部的变量(全局变量)
num = 10
# 定义一个函数
def func():
# 函数体代码
#定义在函数内部的变量(局部变量)
num = 100
变量的作用范围
全局变量:在整个程序范围内都可以直接使用
num = 10
def func():
print(f'在局部作用域中调用num变量:{num}')
print(f'在全局作用域中调用num变量:{num}')
func()
"""
执行结果:
在全局作用域中调用num变量:10
在局部作用域中调用num变量:10
"""
局部变量:在函数的调用过程中,开始定义,函数运行过程中生效,函数执行完毕后,销毁
def func():
num = 10
print(f'在局部作用域中调用num局部变量:{num}')
func()
print(f'在全局作用域中调用num局部变量:{num}')
"""
执行结果:
在局部作用域中调用num变量:10
报错:
NameError: name 'num' is not defined
"""
其报错的根本原因为:计算机的垃圾回收机制
用于识别和回收不再被程序使用的内存,避免内存泄漏并减轻开发者的手动内存管理负担
global关键字
用于在局部作用域中修改全局变量
# 定义全局变量num = 10
num = 10
# 定义一个函数func
def func():
# 尝试在局部作用域中修改全局变量
num = 20
# 调用函数func
func()
# 尝试访问全局变量num
print(num) # 10
上例创建了一个新的局部变量 num = 20,但要求修改全局变量,而不是创建新的局部变量.那么就需要使用global关键字.
# 定义全局变量num = 10
num = 10
# 定义一个函数func
def func():
# 尝试在局部作用域中修改全局变量
global num
num = 20
# 调用函数func
func()
# 尝试访问全局变量num
print(num) # 20
注:
global关键字只是针对不可变数据类型的变量进行修改操作(数值、字符串、布尔类型、元组类型),可变类型可以不加global关键字。
函数的参数
在函数定义与调用时,可根据自己的需求来实现参数的传递.在python中,函数的参数一共有两种形式:
形参:在函数定义时,所编写的参数就称之为形式参数
实参:在函数调用时,所传递的参数就称之为实际参数
def say_hello(name): # 此name为函数定义时编写的形式参数
return 'hello,' + name
name = 'Tian'
say_hello(name) # 此name为函数调用时传递的实际参数
注意:虽然我们在函数传递时,喜欢使用相同的名称作为参数名称。但是两者的作用范围是不同的。name = ‘Tian’,代表实参。其是一个全局变量,而say_hello(name)函数中的name实际是在函数定义时才声明的变量,所以其实一个局部变量。
函数的参数类型
不同参数对比

位置参数
理论上,在函数定义时,我们可以为其定义多个参数。但是在函数调用时,我们也应该传递多个参数,正常情况,其要一一对应。
def describe_pet(animal_type, pet_name):
print(f'我有一只{animal_type},名字叫{pet_name}')
# 调用函数
describe_pet('狗', '美元')# 我有一只狗,名字叫美元
describe_pet('猫', '英镑') # 我有一只猫,名字叫英镑
注意事项:位置参数强调的是参数传递的位置必须一一对应,不能颠倒
关键字参数
函数调用,通过“键=值”形式加以指定。可以让函数更加清晰、容易使用,同时也清除了参数的顺序需求。
def describe_pet(animal_type, pet_name):
print(f'我有一只{animal_type},名字叫{pet_name}')
# 调用函数(使用关键词参数)
describe_pet(animal_type='狗', pet_name='美元') # 我有一只狗,名字叫美元
describe_pet(pet_name='英镑', animal_type='猫') # 我有一只猫,名字叫英镑
describe_pet('狗', pet_name='美元') # 我有一只狗,名字叫美元
# describe_pet(pet_name='英镑', '猫') # 错误! 位置参数不能在关键之参数之后!
缺省参数(参数默认值)
缺省参数也叫默认参数,用于定义函数时为参数提供默认值,调用函数时可不传该默认参数的值(注意:所有位置参数必须出现在默认参数前,包括函数定义和调用)。
def describe_pet(pet_name, animal_type='狗'):
print(f'我有一只{animal_type},名字叫{pet_name}')
# 调用函数
describe_pet('美元') # 我有一只狗,名字叫美元
describe_pet('英镑', '猫') # 我有一只猫,名字叫英镑 (覆盖默认值)
describe_pet('人民币', animal_type='兔子') # 我有一只兔子,名字叫人民币 (关键字覆盖)
谨记:我们在定义缺省参数时,一定要把其写在参数列表的最后侧
不定长参数
不定长参数也叫可变参数。用于不确定调用的时候会传递多少个参数(不传参也可以)的场景。此时,可用包裹(packing)位置参数,或者包裹关键字参数,来进行参数传递,会显得非常方便。
不定长元组(位置)参数
def add_all(*args):
"""把传进来的所有数字相加"""
print(args) # 元组类型数据,对传递参数有顺序要求
summer = 0
for num in args:
summer += num
return summer
# or
# return sum(args) 直接使用sum函数不用遍历元组
# 调用函数,传递参数
print(add_all(10)) # 10
print(add_all(10, 20)) # 30
print(add_all(10, 20, 30, 40)) #100
不定长字典(关键字)参数
def add_all(**kwargs):
"""相加所有value值"""
print(kwargs) # 字典类型数据,对传递参数没有顺序要求,格式要求key = value值
summer = 0
for num in kwargs.values():
summer += num
return summer
# or
# return sum(kwargs.values()) 直接使用sum函数不用遍历列表
# 调用函数,传递参数
print(add_all(first=40, second=50, third=60)) # 150
kwargs = keyword + args
总结:无论是包裹位置传递还是包裹关键字传递,都是一个组包的过程。
Python组包:就是把多个数据组成元组或者字典的过程。
二者混用案例
def add_all(*args, **kwargs):
"""求元组和字典值的总和"""
print(args)
print(kwargs)
summer = 0
for num in args:
summer += num
for num in kwargs.values():
summer += num
return summer
# or
# return sum(args)+sum(kwargs.values())
# 定义一个元组(也可以是列表)
tuple1 = (10, 20, 30)
# 定义一个字典
dict1 = {'first': 40, 'second': 50, 'third': 60}
# 如果想把元组传递给*args,必须在tuple1的前面加一个*号
# 如果想把字典传递给**kwargs,必须在dict1的前面加两个**号
print(add_all(*tuple1, **dict1))
lambda函数
在Python中,函数大多数是有名函数 => 普通函数。但是有些情况下,我们为了简化程序代码,也可以定义匿名函数 => lambda表达式
应用场景
如果一个函数有一个返回值,并且只有一句代码,可以使用 lambda简化。
基本语法
变量 = lambda 函数参数:表达式(函数代码 + return返回值)
# 调用变量
变量()
lambda表达式:
def fn1():
return 100
# 调用fn1函数
print(fn1())
用lambda表达式对fn1函数进行简化:
fn2 = lambda : 100
# 调用fn1函数
print(fn2())
带参数的lambda表达式
def fn1(num1, num2):
return num1 + num2
print(fn1(10, 20))
用lambda表达式对fn1函数进行简化:
fn2 = lambda num1, num2: num1 + num2
print(fn2(10, 20))
带默认参数的lambda表达式
fn = lambda a, b, c=100: a + b + c
print(fn(10, 20))
带if判断(三目运算符)的lambda表达式
fn = lambda a, b: a if a > b else b
print(fn(10, 20))
案例:
知识点:列表.sort(key=排序的key索引, reverse=True)
# 列表数据+字典数据排序
students = [
{'name': 'Tom', 'age': 20},
{'name': 'Rose', 'age': 19},
{'name': 'Jack', 'age': 22}
]
# 按name值升序排列
students.sort(key=lambda x: x['name'])
print(students)
"""
[{'name': 'Jack', 'age': 22}, {'name': 'Rose', 'age': 19}, {'name': 'Tom', 'age': 20}]
"""
# 按name值降序排列
students.sort(key=lambda x: x['name'], reverse=True)
print(students)
"""
[{'name': 'Tom', 'age': 20}, {'name': 'Rose', 'age': 19}, {'name': 'Jack', 'age': 22}]
"""
# 按age值升序排列
students.sort(key=lambda x: x['age'])
print(students)
"""
[{'name': 'Rose', 'age': 19}, {'name': 'Tom', 'age': 20}, {'name': 'Jack', 'age': 22}]
"""
python异常处理
什么是异常
当检测到一个错误时,解释器就无法继续执行了,反而出现了一些错误的提示,这就是所谓的"异常"。
异常演示
num = int(input('请输入一个正整数'))
# 当程序输入字符串时,程序会就报错
报错:

异常捕获
try:
可能发生错误的代码
except:
如果出现异常执行的代码
try…except主要用于捕获代码运行时异常,如果异常发生,则执行except中的代码
案例:
try:
num = int(input('请输入一个正整数: '))
except: # 更准确的写法为 except ValueError:
print('输入无效,请输入正整数')
异常捕获并输出错误信息
无论我们在except后面定义多少个异常类型,实际应用中,也可能会出现无法捕获的未知异常。这个时候,我们考虑使用Exception异常类型捕获可能遇到的所有未知异常:
try:
可能发生错误的代码
except Exception as e:
print(e)
案例:
# 打印一个未定义变量
try:
print(name)
except Exception as e:
print(e)
# name 'name' is not defined
异常捕获中else语句
else语句:表示的时如果没有异常要执行的代码
try:
print('执行函数')
except Exception as e:
print(e)
else:
print('恭喜,没有任何异常')
案例:
try:
num = int(input('请输入一个正整数: '))
except Exception as e:
print(e)
else:
print(num)
异常捕获中finally语句
finally语句:表示无论是否异常都要执行的代码
try:
num = int(input('请输入一个正整数: '))
except Exception as e:
print(e)
else:
print(num)
finally:
print('执行结束') # 无论上述代码是否报错,都会打印'执行结束'
异常案例
升级猜数字游戏,增加程序健壮性,用户在输入过程中可能不会输入数字或者不按照要求输入,程序要能捕获到用户的异常输入。在已有的猜数游戏中加入异常功能。
import random
def guess_number_game():
# 1. 随机生成1个 1 ~ 100之间的数字, 让用户来猜.
guess_num = random.randint(1, 100)
while True:
try:
# 2. 键盘录入, 表示: 玩家出拳的编号.
input_num = int(input('请录入您要猜的整数 (1-100): '))
# 3. 判断用户是否猜对了, 并提示. 猜对, 猜大, 猜小.
if input_num == guess_num:
print('恭喜您, 猜对了, 请找夯老师领取奖品, 练习题一套!')
break
elif input_num > guess_num:
print('哎呀, 您猜大了!')
else:
print('哎呀, 您猜小了!')
except ValueError:
print('输入无效,请输入一个整数!')
# 调用猜数字游戏函数
guess_number_game()
更多推荐


所有评论(0)