Python中函数介绍及其使用


前言

本文的主要内容是Python中函数介绍及其使用,具体包括定义函数、传递参数、函数返回值、传递列表与任意数量的实参以及将函数存储在模块中等部分,文中附有代码以及相应的运行结果辅助理解。


一、定义函数

函数是带有名字的代码块,其用于完成具体的工作,有时候需要在程序中多次执行同一项任务,如果每次都写相同的代码,程序就会显得又长又繁琐,可读性也不好,此时可以将这一项特定的任务写为函数体,在程序需要的时候调用执行该函数即可,这样一来,程序的编写、可读性、测试和修改都将变得更加容易。
下面是最简单的函数应用,即调用函数打印一句话。

def msg_print():
    """打印消息"""   #这行是文档字符串的注释,用来解释函数的功能
    print('Hello!') #后面的所有缩进行构成了函数体

msg_print()  #调用函数

运行结果如下图所示。
在这里插入图片描述
在上面的例子中,函数名后面的括号内是空的,一般情况下,在调用函数时都会向函数传递参数信息。
在函数定义时传递的参数是形参,形参是函数完成其工作所需的一项信息;在函数调用时传递的参数是实参,实参是调用函数时传递给函数的信息。
下面是向函数传递参数的例子。

def msg_print(name):  #这里的name是形参
    """打印消息"""
    print('Hello, ' + name.title() + '!')
    
msg_print('emma')  #这里的'emma'是实参

运行结果如下图所示。
在这里插入图片描述


二、传递实参

函数定义中可能包含多个形参,因此函数在调用时也就包含多个实参。向函数传递实参的方式很多,有位置实参、关键字实参,还可使用列表和字典。

1.位置实参

使用位置实参要求实参的顺序与形参的顺序相同,否则在调用函数的过程中会发生类型错误或者逻辑错误。
下面是位置实参应用的例子。

def user_info(name, fruit):
    """打印用户信息"""
    print('My name is ' + name.title() + '.')
    print('I like ' + fruit + ' best.')
    
user_info('emma','apple')   #正确调用,实参与形参顺序一一对应
user_info('apple', 'emma')  #错误调用

运行结果如下图所示。
在这里插入图片描述
由运行结果可以看到,位置实参一定要和形参顺序一致,这样才不会使错误发生。

2.关键字实参

关键字实参中每个实参都是由变量名和值组成的,它传递给函数的实参是名称值对,因为在实参中将名称和值已经关联起来了,所以无需再考虑函数调用中的实参顺序。
下面是关键字实参应用的例子。

def user_info(name, fruit):
    """打印用户信息"""
    print('My name is ' + name.title() + '.')
    print('I like ' + fruit + ' best.')

user_info(name = 'emma',fruit = 'apple')
user_info(fruit = 'apple', name = 'emma')

运行结果如下图所示。
在这里插入图片描述
由运行结果可知,使用关键字实参无需再担心实参与形参的顺序对应一致,只需要将名称和值对应上即可。

扫描二维码关注公众号,回复: 14411654 查看本文章

3.给形参指定默认值

编写函数时,可给每个形参指定默认值,若调用的函数提供了实参,Python将使用指定的实参值,如果没有提供实参,将使用形参的默认值。因此,给形参指定默认值后,可在函数调用中省略相应的实参。
下面是给形参指定默认值的例子。

def user_info(name='emma', fruit='apple'):  #给形参指定默认值
    """打印用户信息"""
    print('My name is ' + name.title() + '.')
    print('I like ' + fruit + ' best.')

user_info()   #省略已有默认值的实参
user_info('alice')   #只传一个实参,默认传给第一个位置
user_info(fruit='pear')   #如果要传参给非第一位置,使用关键字实参的方法
user_info('lisa', 'banana')   #提供实参则覆盖默认值

运行结果如下图所示。
在这里插入图片描述


三、函数返回值

函数并非总是直接显示输出,它也可以处理一些数据并返回一个或一组值,函数返回的值被称为返回值。在函数中,可使用return语句将值返回到调用函数的代码行,返回值能够将程序的大部分繁重工作移到函数中去完成,从而简化主程序。

1.返回简单值

下面是函数返回简单值的例子。

def name(first_name, last_name):
    """返回用户全名"""
    full_name = first_name.title() + ' ' +last_name.title()
    return full_name

print(name('lebron','james')) #调用函数并打印

运行结果如下图所示。
在这里插入图片描述
当然有的人有中间名,这就用到了上面学到的默认值,将中间名形参默认设置为空,这样在函数调用时就能够应对有中间名的情况了。
下面是该例子的扩展。

def name(first_name, last_name, middle_name=''):
    """返回用户全名"""
    if middle_name: #中间名非空
        full_name = first_name.title() + ' ' + middle_name.title() + ' ' + last_name.title()
    else:
        full_name = first_name.title() + ' ' +last_name.title()
    return full_name

print(name('lebron', 'james')) #调用函数并打印
print(name('john', 'green', 'joe')) #调用函数并打印

运行结果如下图所示。
在这里插入图片描述

2.返回字典

函数可返回任何类型的值,包括列表和字典等较复杂的数据结构。
下面是函数返回字典的例子。

def name(first_name, last_name):
    """返回一个字典"""
    full_name = {
    
    'first_name': first_name, 'last_name': last_name}
    return full_name

print(name('lebron', 'james')) #调用函数打印字典

运行结果如下图所示。
在这里插入图片描述

3.结合使用函数和while 循环

下面是一个结合使用函数和while循环的例子。

def name(first_name, last_name):
    """返回用户全名"""
    full_name = first_name.title() + ' ' +last_name.title()
    return full_name

while True:
    first_name = input('Please input your first name: ')
    last_name = input('Please input your last name: ')   #用户输入
    
    print('Your name is ' + name(first_name, last_name) + '.') #调用函数并打印
   
    quit = input("Enter 'q' to end, and other keys to continue.") #根据用户输入决定是否退出while循环
    if quit == 'q':
        break

运行结果如下图所示。
在这里插入图片描述


四、传递列表

有时候,将列表传递给函数可以提高处理列表的效率。此外,在函数中对列表所做的任何修改都是永久性的。

1.在函数中调用列表

下面是一个在函数中调用列表的简单例子。

def fruit_msg(fruits):
    """访问列表中的每个元素"""
    for fruit in fruits:  #逐个访问列表元素
       print('I like ' + fruit + '.')

fruits = ['grapes', 'apples', 'bananas', 'oranges', 'pears']
fruit_msg(fruits)  #调用函数访问列表

运行结果如下图所示。
在这里插入图片描述

2.在函数中修改列表

在函数中不仅可以调用列表,还可以修改列表,不过这种修改是永久性的。
下面是一个在函数中修改列表的例子。

def print_msg(fruit_1, fruit_2):
    """修改列表,打印列表fruit_1中的每个元素并删除,将其添加到列表fruit_2中"""
    while fruit_1:   #列表fruit_1非空时执行while语句
        fruit = fruit_1.pop()   #逐个删除列表fruit_1中的元素
        print('I like ' + fruit + '.')
        fruit_2.append(fruit)  #将删除的元素添加到列表fruit_2中

def print_element(fruits):
    """遍历列表元素"""
    for fruit in fruits:
        print('\t' + fruit)

fruit_1 = ['grapes', 'apples', 'bananas', 'oranges', 'pears']
fruit_2 = []

print_msg(fruit_1, fruit_2)  #调用函数修改列表,这里传递的是原列表
print('列表fruit_1的元素: ')
print_element(fruit_1) #遍历列表fruit_1
print('列表fruit_2的元素: ')
print_element(fruit_2) #遍历列表fruit_2

运行结果如下图所示。
在这里插入图片描述

3.禁止在函数中修改列表

上面已经提到过了,在函数中对列表所做的任何修改都是永久性的,有时候可能需要保留原列表,这时就可以向函数传递列表的副本。
下面是禁止在函数中修改列表的例子。

def print_msg(fruit_1, fruit_2):
    """修改列表,打印列表fruit_1中的每个元素并删除,将其添加到列表fruit_2中"""
    while fruit_1:   #列表fruit_1非空时执行while语句
        fruit = fruit_1.pop()   #逐个删除列表fruit_1中的元素
        print('I like ' + fruit + '.')
        fruit_2.append(fruit)  #将删除的元素添加到列表fruit_2中

def print_element(fruits):
    """遍历列表元素"""
    for fruit in fruits:
        print('\t' + fruit)

fruit_1 = ['grapes', 'apples', 'bananas', 'oranges', 'pears']
fruit_2 = []

print_msg(fruit_1[:], fruit_2)  #调用函数修改列表,这里传递的是原列表的副本
print('列表fruit_1的元素: ')
print_element(fruit_1) #遍历列表fruit_1
print('列表fruit_2的元素: ')
print_element(fruit_2) #遍历列表fruit_2

运行结果如下图所示。
在这里插入图片描述
对比上面两段代码,只有一行发生了简单的变化,就是在给函数传递原列表时,传递给其列表的副本即可,这样在执行完程序时原列表就不会发生变化。


五、传递任意数量的实参

有时候,我们预先不知道函数需要接受多少个实参,不过Python允许函数从调用语句中收集任意数量的实参。

1.传递任意数量实参的简单例子

下面是一个传递任意数量实参的简单例子。

def print_msg(*fruits):
    """打印所有信息"""
    print(fruits)

print_msg('apples')
print_msg('bananas', 'pears', 'mangoes')

运行结果如下图所示。
在这里插入图片描述
由上面的运行结果可以看出,传递的任意数量实参存储在元组中,我们也可以改写代码遍历元组。
改写后的代码如下。

def print_msg(*fruits):
    """打印所有信息"""
    for fruit in fruits:  #遍历元组
        print('I like ' + fruit + '.')

print_msg('apples')
print_msg('bananas', 'pears', 'mangoes')

运行结果如下图所示。
在这里插入图片描述

2.结合使用位置实参和任意数量实参

如果要让函数接受不同类型的实参,必须在函数定义中将接纳任意数量实参的形参放在最后,Python先匹配位置实参和关键字实参,再将余下的实参都收集到最后一个形参中。
下面是结合使用位置实参和任意数量实参的例子。

def print_msg(name, age, *fruits): #传递不同类型的参数
    """结合使用位置实参和任意数量实参"""
    print('My name is ' + name.title() + ', I am ' + str(age) +' years old, and I like :')
    for fruit in fruits:  #遍历元组
        print('\t' + fruit)

print_msg('emma', 12, 'apples')
print_msg('lisa', 20,  'bananas', 'pears', 'mangoes')

运行结果如下图所示。
在这里插入图片描述

3.使用任意数量的关键字实参

有时候需要接受任意数量的实参,但预先不知道传递给函数的会是什么样的信息,在这种情况下可将函数编写成能够接受任意数量的键值对,将其写入到字典中。
下面是使用任意数量的关键字实参的例子。

def user_info(name, age, **other_info):  #注意这里一定是双星号
    """使用任意数量的关键字实参"""
    users = {
    
    }  #创建空字典
    users['name'] = name  #在字典中加入已知的键值对
    users['age'] = age
    
    for key, value in other_info.items(): #遍历其他参数信息添加到字典中
        users[key] = value
    return users

print(user_info('Emma', 12, favorite_color='red', favorite_fruit='apple')) #调用函数并打印
print(user_info('Lisa', 20, favorite_color='green', favorite_fruit='watermelon', favorite_sport='basketball'))

运行结果如下图所示。
在这里插入图片描述


六、将函数存储在模块中

函数的优点之一是可将代码块与主程序分离,将函数存储在被称为模块的独立文件中,再将模块导入到主程序中,import语句允许在当前运行的程序文件中使用模块中的代码。
通过将函数存储在独立的文件中,可隐藏程序代码的细节,将重点放在程序的高层逻辑上,此外,这样做还能让你在不同的程序中重用函数。将函数存储在独立文件中后,这些文件就可以共享。

1.导入整个模块

要让函数是可导入的,得先创建模块,模块是扩展名为.py的文件,其中包含要导入到主程序中的代码。
在上面的例子中进行修改,先新建一个名为function.py的模块文件,在其中写入如下代码。

def print_msg(fruit_1, fruit_2):
    """修改列表,打印列表fruit_1中的每个元素并删除,将其添加到列表fruit_2中"""
    while fruit_1:   #列表fruit_1非空时执行while语句
        fruit = fruit_1.pop()   #逐个删除列表fruit_1中的元素
        print('I like ' + fruit + '.')
        fruit_2.append(fruit)  #将删除的元素添加到列表fruit_2中

def print_element(fruits):
    """遍历列表元素"""
    for fruit in fruits:
        print('\t' + fruit)

然后在主程序文件中调用该模块中的函数,代码如下。

import function  #导入文件function.py,即将其中的所有函数都复制到这个程序中
fruit_1 = ['grapes', 'apples', 'bananas', 'oranges', 'pears']
fruit_2 = []

function.print_msg(fruit_1[:], fruit_2)  
#调用被导入模块中的函数时,可指定导入的模块的名称和函数名,并用句点分隔它们
print('列表fruit_1的元素: ')
function.print_element(fruit_1) #遍历列表fruit_1
print('列表fruit_2的元素: ')
function.print_element(fruit_2) #遍历列表fruit_2

上面的例子在调用函数时需要使用模块名、句点以及函数名才能完成函数的调用。
运行结果如下图所示。
在这里插入图片描述
可以看到,上面代码的运行结果与函数和程序在一个文件中的运行结果一致。

2.使用as给模块指定别名

要给模块指定别名,可以在导入模块时使用as给模块指定别名,代码示例如下。

import function as f
#导入文件function.py到主程序中并给其指定别名为f

下面的这段主程序代码的功能和上面的主程序代码功能一致。

import function as f #导入模块function并给其指定别名为f
fruit_1 = ['grapes', 'apples', 'bananas', 'oranges', 'pears']
fruit_2 = []

f.print_msg(fruit_1[:], fruit_2)  #调用函数使用模块名时用别名
print('列表fruit_1的元素: ')
f.print_element(fruit_1)
print('列表fruit_2的元素: ')
f.print_element(fruit_2)

3.导入特定的函数

模块中存储的函数一般有很多,有时候我们只需要导入特定的函数。
比如要导入上面function.py模块中的print_msg()函数,可以用如下代码。

from function import print_msg  
#从模块名为function.py的文件中导入函数print_msg,注意这里的函数不带括号

如果要从模块中导入多个函数,可以用逗号隔开,代码示例如下。

from function import print_msg, print_element
#从模块名为function.py的文件中导入函数print_msg和print_element,注意这里的函数不带括号

下面这段主程序代码与上面的主程序代码功能是一致的,在调用函数时直接指定函数名称即可。

from function import print_msg, print_element #从模块中导入特定的函数
fruit_1 = ['grapes', 'apples', 'bananas', 'oranges', 'pears']
fruit_2 = []

print_msg(fruit_1[:], fruit_2)  #调用函数时直接指定函数名称,无需使用句点
print('列表fruit_1的元素: ')
print_element(fruit_1) #遍历列表fruit_1
print('列表fruit_2的元素: ')
print_element(fruit_2) #遍历列表fruit_2

4.使用as给函数指定别名

如果要导入的函数名称可能与程序中现有的名称冲突,或者函数的名称太长,可指定简短而独一无二的别名,即函数的另一个名称,类似于外号,要给函数指定别名,需要在导入它时使用as指定别名。
代码示例如下。

from function import print_msg as pm
#从模块名为function.py的文件中导入函数print_msg,并指定其别名为pm,这样在使用时用pm即可

需要注意的是,给函数指定别名后,在主程序中调用该函数只能用其别名,原来的函数名将不能使用。
下面的这段主程序代码的功能也和上面的主程序代码功能一致,在调用函数时使用其别名调用。

from function import print_msg as pm, print_element as pe #从模块中导入特定的函数并起别名
fruit_1 = ['grapes', 'apples', 'bananas', 'oranges', 'pears']
fruit_2 = []

pm(fruit_1[:], fruit_2) #调用函数时只能使用别名
print('列表fruit_1的元素: ')
pe(fruit_1) #遍历列表fruit_1
print('列表fruit_2的元素: ')
pe(fruit_2) #遍历列表fruit_2

5.导入模块中的所有函数

导入模块中的所有函数使用如下代码。

from function import *
#从模块名为function.py的文件中导入所有函数

导入模块中的所有函数后,调用函数时不需要用句点,直接使用函数名调用即可。
下面这段主程序代码与上面的主程序代码功能也是一致的。

from function import *  #从模块中导入所有的函数
fruit_1 = ['grapes', 'apples', 'bananas', 'oranges', 'pears']
fruit_2 = []

print_msg(fruit_1[:], fruit_2)  #调用函数时直接指定函数名称
print('列表fruit_1的元素: ')
print_element(fruit_1) #遍历列表fruit_1
print('列表fruit_2的元素: ')
print_element(fruit_2) #遍历列表fruit_2

七、猜数字游戏

还记得本书前言中的这个猜数字游戏吗?上一篇文章Python中用户输入与while循环中已经编写过了。
在这里插入图片描述
下面是使用函数实现该游戏的代码。

import random

def func(input_num, thinking_num):
    """定义函数用于比较输入数与预想数的大小,两者相等时退出函数"""
    while input_num != thinking_num:
        if input_num < thinking_num:
            input_num = input("Too low! Guess again: ")
            input_num = int(input_num)
        elif input_num > thinking_num:
            input_num = input("Too high! Guess again: ")
            input_num = int(input_num)

sign = True  #标志位置为 True
while sign:
    number = random.randint(1, 100)  # 随机生成一个1-100内的随机数作为预想数
    num = input("I'm thinking of a number! Try to guess the number I'm thinking of: ")
    
    func(int(num), number)  #调用函数比较用户输入数值与预想数值的大小关系
    
    y_or_n = input("That's it! Would you like to play again? (yes/no): ")
    if y_or_n == 'no':  #用户输入no时退出游戏
        sign = False  #标志位置为 False
        print("Thanks for playing!")

运行结果如下图所示。
在这里插入图片描述
由上面的运行结果可以看到,代码能够按照要求运行并给予用户反馈,这就是一个简单的人机交互小游戏。


总结

以上就是Python中函数介绍及其使用的所有内容了,在编写函数时,应给函数指定描述性名称,且只在其中使用小写字母和下划线,给模块命名时也应如此,每个函数都应包含简要地阐述其功能的注释,该注释应紧跟在函数定义后面。总之,在编写函数的过程中应尽可能的规范编写代码,这样在调用函数时,不管是自己还是别人都能够很好的理解。
本文参考书目:Python 编程 :从入门到实践 / (美) 埃里克•马瑟斯(Eric Matthes)著;袁国忠译

猜你喜欢

转载自blog.csdn.net/weixin_42570192/article/details/123805206