第4章:函数

一、什么是函数?

前面我们已经学习并使用过 print()、input() 这类内置函数,相信大家一定有一些思考,了解到这些内置函数,其实就是将一些功能组合起来,通过 函数名 可以直接使用,而这类函数,其实我们也可以 自己创建

甚至我们可以在原有 函数(或内置函数) 基础上,根据自己需要,再次创建一个新的函数,从而实现更为复杂的功能。

接下来,我们可以快速的使用代码来体会下 “函数” 的意义!

# 我们的需求:创建一个函数,每使用该函数1次,即打印100次“我钟意你!”
# 创建一个py文件,代码内容如下。
def say_love():
    for i in range(0, 100):
        print("我钟意你!")

say_love() 

我们可以看到,每调用一次“say_love()函数”控制台的重复输出了100次“我钟意你!”。

函数 带来的意义有哪些?

  • 减少重复代码。
  • 减少更新代码的代价。
  • 代码变得更 “短、易读、更新”

二、函数的基础构成!

通过前面的样例,我们大致能够猜出 函数的基础构成,有哪些?

def # 定义函数的关键字。
(如果你仔细学习过《第3章》布尔值部分,你会发现def属于关键字。)
say_love():
# say_love 函数名,之前有讲过函数命名规则。
# () 参数,函数内的方法,通过接收参数,实现功能,比如print(),可以接收“字符串”,打印到控制台。之后我们会详细讲解“参数”的作用和使用。(注:空括号,表示该函数不需要接收参数)
#: 这个没什么好解释的,固定格式,必须在()之后,添加这个符号。
# 代码块,即该函数实现的功能具体代码块,具体写法本章节会细讲。
for i in range(0, 100):
        print("我钟意你!")

那么我们改进下这个函数,加入“参数”,看看效果。

# 根据参数num,打印num次"我钟意你!"。
# 你会发现,在调用函数时,需要传入一个参数,这个参数会控制该函数的行为结果。当然参数会有很多种写法,我们本章节会继续详细讲一讲。
def say_love_num(num):
    for i in range(0, num):
        print("我钟意你!")

say_love_num(3)

你可能已经发现:如果不调用函数,函数是不会被执行的。

学习之前,我希望能够对于以下几个“专业术语”有所记忆。

定义:定义一个函数,可以理解为“创建一个函数”。

调用:我们刚才执行的“say_love() ”,就是调用的行为,指调用该“函数”。

传递:刚才第2个代码示例中,调用函数时,我们传入参数“3”,即将该参数传递给该函数,使它能够打印3遍内容。

** 假如你不太好记忆参数,我建议你可以这样理解,函数定义的参数可以叫做“形参”,调用函数传入的参数叫做“实参”。“实参”传递给该方法对应的“形参”,从而根据代码具体实现效果,输出或返回结果。

三、函数的参数。

刚才我们已经通过示例,了解到参数的一些作用,接下来,我们就详细说说参数都有哪些一定要知道的知识。

建议自己一边理解一边跟着练习一遍这些代码,运行看看结果。

位置参数

调用函数时根据函数定义的 参数位置传递参数

注意:传递和定义的参数的顺序及个数必须一致

def user_info(name, age, sex):
    print(f"姓名:{name},年龄{age},性别{sex}")

user_info("测试划水老师傅", 30, "男")
#运行结果:姓名:测试划水老师傅,年龄30,性别男

关键字参数

函数调用,通过 “键 = 值” 的形式指定。可以让函数更加清晰、容易使用,同时 不需要注意函数的顺序

def user_info(name, age, sex):
    print(f"姓名:{name},年龄{age},性别{sex}")

user_info(age=30,name="测试划水老师傅",sex="男")
#运行结果:姓名:测试划水老师傅,年龄30,性别男

缺省参数

也叫默认参数,用于定义函数,为参数提供默认值,调用函数时,可以不传入该默认参数的值。

注意:所有位置参数必须写在默认参数前,包括函数定义和调用)

def user_info(name, age, sex="男"):
    print(f"姓名:{name},年龄{age},性别{sex}")

user_info(age=30,name="测试划水老师傅")
#运行结果:姓名:测试划水老师傅,年龄30,性别男

不定长参数-位置参数

不定长参数也叫可变参数。

用于不确定调用时,会传入多少个参数(不传参数也可以)的场景。

此时,用包裹(packing)位置的参数,或者包裹关键字参数,来进行参数传递,会显得非常方便。

注意:

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

什么叫“元组”,我们不用关心,后续会讲到,目前你只需记住,函数的参数有这么一个写法即可。

def user_info(*args):
    print(args)

user_info("测试划水老师傅", 30)
#运行结果:('测试划水老师傅', 30)

不定长参数-关键字参数

收集所有关键字参数,返回一个“字典”.

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

user_info(name = "测试划水老师傅", age = 30)
#运行结果:{'name': '测试划水老师傅', 'age': 30}

不定长参数“位置参数”、“关键字参数”,无论是包裹位置还是包裹关键字传递,都是一个组包的过程。

四、函数的返回值。

例如:我们去水果店买水果,付钱后,商家会给我们等价的苹果。

那么,在函数中,如果需要返回函数结果,需要使用return。

def shoopping():
    return "又红又大的苹果"

goods = shoopping()
print(goods)

特点:

  • 返回函数结果。
  • return运行后,该函数结束,即return后编写代码不执行。(不信,你可以在return之后,在这个函数内些其他打印语句试试)

五、函数返回值的进阶玩法!

返回值作为参数传递

def test_A():
    str = "Python"
    return str

def test_B(book):
    print(book)

result = test_A()
test_B(result)
#运行结果:Python

return 多个数据,并且定义返回的数据类型。

def test_A():
    str_1 = "Python"
    str_2 = "Java"
    return str_1, str_2

def test_B():
    str_1 = "Python"
    str_2 = "Java"
    return (str_1, str_2)

def test_C():
    str_1 = "Python"
    str_2 = "Java"
    return [str_1, str_2]

def test_D():
    str_1 = "Python"
    str_2 = "Java"
    return {"key1":str_1,"key2":str_2}

def test_E():
    str_1 = "Python"
    str_2 = "Java"
    return f"{str_1}{str_2}"

def print_return(book):
    print(book)

result_1 = test_A()
print(result_1)
print(type(result_1))
result_2 = test_B()
print(result_2)
print(type(result_2))
result_3 = test_C()
print(result_3)
print(type(result_3))
result_4 = test_D()
print(result_4)
print(type(result_4))
result_5 = test_E()
print(result_5)
print(type(result_5))
#运行结果:
('Python', 'Java')
<class 'tuple'>
('Python', 'Java')
<class 'tuple'>
['Python', 'Java']
<class 'list'>
{'key1': 'Python', 'key2': 'Java'}
<class 'dict'>
Python、Java
<class 'str'>

函数的嵌套写法。指一个函数里面又调用另外一个函数。

def shoopping(book_name):
    """
    这是一个介绍return的简单函数
    :return: "《Python核心编程》"
    """
    return "《Python核心编程》"


def need_pay_num(book_name):
    if book_name == "《Python核心编程》":
        return "你需要支付60元"

print(shoopping("《Python核心编程》"))
print(need_pay_num("《Python核心编程》"))
#运行结果:
《Python核心编程》
你需要支付60

六、函数的说明文档。

我们如果需要将代码交给其他人,一般会这些生成函数文档,并且这也是一个好的代码注释习惯。```

def shoopping():
    """
    这是一个介绍return的简单函数
    :return: "《Python核心编程》"
    """
    return "《Python核心编程》"

help(shoopping)
# 运行结果:
Help on function shoopping in module __main__:
shoopping()
    这是一个介绍return的简单函数
    :return: "《Python核心编程》"

七、局部变量、全局变量和global关键字。

之前的学习,我们发现,一些变量会写在“函数内”、“函数外”。而细心的同学已经发现,这两者的变量作用域(可以使用的范围)是不一样的。

局部变量:是定义在函数体内的变量,只在函数体内部生效,如果在函数体外使用,则代码报错。

全局变量:指在函数体内、外都能生效的变量。

我们结合代码,来理解下。

# 全局变量
a = "测试划水老师傅"
def testA():
    print(a)

testA()
print(a)
运行结果:
测试划水老师傅
测试划水老师傅

注意:

在函数体内部,临时保存数据,当函数体调用完成后,局部变量被销毁。

def testA():
    a = "测试划水老师傅"
    print(a)

testA()
print(a)
运行结果:
测试划水老师傅
Traceback (most recent call last):
  File "E:\****\test.py", line 6, in <module>
    print(a)
NameError: name 'a' is not defined

如果另外一个函数内使用“局部变量”修改“全局变量”会有什么变化?

a = "测试划水老师傅"
def testA():
    print(a)

def testB():
    a = "Python"
    print(a)
testA()
testB()
print(f'全局变量a = {a}')
运行结果:
测试划水老师傅
Python
全局变量a = 测试划水老师傅

利用global关键字,将函数体内的局部变量可以修改为全局变量。

a = "测试划水老师傅"
def testA():
    print(a)

def testB():
    global a
    a = "Python"
    print(a)
testA()
testB()
print(f'全局变量a = {a}')
运行结果:
测试划水老师傅
Python
全局变量a = Python

八、异常处理。

截止目前为止,我们已经遇到很多报错或“异常”,一旦发生异常,程序将终于运行(崩溃)。

那我们一定不希望在实际工作过程中,发生程序终止的问题,而是希望程序能够将这些异常进行处理并继续执行。

比如下面这个代码,发生异常后,后面的程序不会在执行。

def input_print_num():
    num = int(input("输入内容:"))
    print(num)
    print("谢谢使用!")

input_print_num()

我们之前都学过这个,如果此时,我输入的内容为非数字,就会发生下面这个错误。

输入内容:呵呵
Traceback (most recent call last):
  File "E:\code\learning_python_basis\Lesson_code_4\异常处理.py", line 6, in <module>
    input_print_num()
  File "E:\code\learning_python_basis\Lesson_code_4\异常处理.py", line 2, in input_print_num
    num = int(input("输入内容:"))
          ^^^^^^^^^^^^^^^^^^^
ValueError: invalid literal for int() with base 10: '呵呵'

发生报错后,程序停止运行,函数内之后的语句不在执行。

接下来,我们试试加上异常处理,看会有什么结果。

def input_print_num():
    try:
        num = int(input("输入内容:"))
        print(num)
    except ValueError:
        print("输入错误")
    print("谢谢使用!")

input_print_num()
运行结果:
输入内容:按时
输入错误
谢谢使用!

我们发现,程序没有崩溃,会将捕获的错误,按照我们定义的内容进行输出,之后的程序可以继续运行。

练习题

试试将我们上一节课的练习题,运用函数的思想,进行拆解和编写,你会如何去做呢?可以找老师傅讨论。

  • 19
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

测试划水老师傅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值