[Python学习笔记5]——函数

目录

1. 函数的定义

2. 传递实参

2.1 位置实参

2.2 关键字实参

2.3 给形参指定默认值

3. 返回值

3.1 返回简单值

3.2 将形参的默认值指定为空字符串以实现实参可选

3.3 返回字典或列表

4. 传递列表

4.1 向函数传递列表

4.2 在函数中修改列表

4.3 禁止函数修改列表(使用列表切片副本)

5. 传递任意数量的实参

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

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

6. 将函数存储在模块中

8.1 导入整个模块

8.2 导入特定的函数

8.3 使用as给函数指定别名

8.4 使用as给模块指定别名

8.5 导入模块中的所有函数


1. 函数的定义

在Python中,函数可按下面这种方式定义:

def greet_user(username): 
    """ 显示简单的问候语 """ 
    print("Hello, " + username.title() + "!") 

greet_user('jesse')

上面这段代码演示了最简单的函数结构,第一行代码使用关键字def来定义一个函数,def后面的greet_user(username)为函数名,username叫做函数的形参,而'jesse'叫做实参。紧跟在def greet_user(username):后面的所有缩进行构成了函数体。""" 显示简单的问候语 """叫做文档字符串,描述的函数是做什么的,文档字符串用三引号括起,Python使用它们来生成有关程序中函数的文档。要使用这个函数,可调用它,依次指定函数名以及要传入括号中的参数。上面这段代码的输出为:

Hello, Jesse!

2. 传递实参

鉴于函数定义中可能包含多个形参,因此函数调用中也可能包含多个实参。向函数传递参数的方式很多,可使用位置实参,这要求实参的顺序与形参的顺序相同;也可使用关键字实参,其中每个实参由变量名和值组成;还可使用列表和字典。下面将一一介绍

2.1 位置实参

在调用函数时,Python必须将函数调用中的每个实参都关联到函数定义中的一个形参,为此,最简单的关联方式是基于实参的顺序,这种关联方式被称为位置实参:

def describe_pet(animal_type, pet_name):
    """ 显示宠物的信息 """ 
    print("\nI have a " + animal_type + ".") 
    print("My " + animal_type + "'s name is " + pet_name.title() + ".") 

describe_pet('hamster', 'harry')

如上面的代码所示,在函数调用中,实参'hamster'存储在形参animal_type中,而实参'harry'存储在形参pet_name中,即实参按位置依次存储在两个形参中,最后的输出结果为:

I have a hamster. 
My hamster's name is Harry.

2.2 关键字实参

关键字实参是传递给函数的名称—值对。在调用函数时,可在实参中将名称和值关联起来,这样在函数传递参数时就不会有参数传递错误的烦恼。关键字实参让你无需考虑函数调用中的实参顺序,还清楚地指出了函数调用中各个值的用途。如下所示为在调用函数时使用关键字实参:

def describe_pet(animal_type, pet_name): 
    """ 显示宠物的信息 """ 
    print("\nI have a " + animal_type + ".") 
    print("My " + animal_type + "'s name is " + pet_name.title() + ".") 

describe_pet(animal_type='hamster', pet_name='harry')

在上面的代码中,在调用函数时使用了关键字实参,其输出结果与2.1中的结果一样,值得注意的是,关键字实参的顺序无关紧要,如下面两个函数的调用是等效的:

describe_pet(animal_type='hamster', pet_name='harry') 
describe_pet(pet_name='harry', animal_type='hamster')

2.3 给形参指定默认值

编写函数时,可给每个形参指定默认值。在调用函数中给形参提供了实参时,函数将使用指定的实参值,否则将使用形参的默认值,如下所示:

def describe_pet(pet_name, animal_type='dog'): 
    """ 显示宠物的信息 """ 
    print("\nI have a " + animal_type + ".") 
    print("My " + animal_type + "'s name is " + pet_name.title() + ".") 

describe_pet(pet_name='willie')
describe_pet('willie')

在上面的代码中,调用函数时,没有给形参animal_type传入实参的值,因此形参animal_type将使用默认值'dog'作为要传入的实参值,其输出结果为:

I have a dog. 
My dog's name is Willie.

I have a dog. 
My dog's name is Willie.

值得注意的是,在给形参指定默认值后,要是想用位置实参,则需要在函数定义时将指定了默认值的形参放在末尾,防止参数传递错误。

当然,你也可以在调用函数时传入实参以覆盖掉默认值,像下面这样:

describe_pet(pet_name='harry', animal_type='hamster')
describe_pet('harry', 'hamster')

此时,函数的输出结果为:

I have a hamster.
My hamster's name is Harry.

I have a hamster.
My hamster's name is Harry.

3. 返回值

3.1 返回简单值

在Python的函数中,可以使用return来返回一个值,如下所示:

def get_formatted_name(first_name, last_name): 
    """ 返回整洁的姓名 """ 
    full_name = first_name + ' ' + last_name 
    return full_name.title()

musician = get_formatted_name('jimi', 'hendrix') 
print(musician)

在上面的代码中,调用函数get_formatted_name()时,会将整理好的姓名返回,并存储在变量musician中,其输出结果为:

Jimi Hendrix

3.2 将形参的默认值指定为空字符串以实现实参可选

有时候,需要让实参变成可选的,这样使用函数的人就只需在必要时才提供额外的信息,如下所示:

def get_formatted_name(first_name, last_name, middle_name=''): 
    """ 返回整洁的姓名 """ 
    if middle_name: 
        full_name = first_name + ' ' + middle_name + ' ' + last_name 
    else: 
        full_name = first_name + ' ' + last_name return full_name.title() 

musician = get_formatted_name('jimi', 'hendrix') 
print(musician) 

musician = get_formatted_name('john', 'hooker', 'lee') 
print(musician)

在上面的代码中,将形参middle_name指定为空字符串,这样在调用函数时就可不向其传入参数。

3.3 返回字典或列表

函数可返回任何类型的值,包括字典和列表等较复杂的数据结构,如下所示:

def build_person(first_name, last_name): 
    """ 返回一个字典,其中包含有关一个人的信息 """ 
    person = {'first': first_name, 'last': last_name} 
    return person 

musician = build_person('jimi', 'hendrix') 
print(musician)

其输出结果为:

{'first': 'jimi', 'last': 'hendrix'}

4. 传递列表

4.1 向函数传递列表

有时候,向函数传递列表很有用,这种列表包含的可能是名字、数字或更复杂的对象(如字典)。将列表传递给函数后,函数就能直接访问其内容,如下所示:

def greet_users(names): 
    """向列表中的每位用户都发出简单的问候""" 
    for name in names: 
        msg = "Hello, " + name.title() + "!" 
        print(msg) 

usernames = ['hannah', 'ty', 'margot']
greet_users(usernames)

在上面的代码中,将一个列表传入了函数,并在函数中对其进行遍历打印,其输出结果为:

Hello, Hannah! 
Hello, Ty! 
Hello, Margot!

4.2 在函数中修改列表

将列表传递给函数后,函数就可对其进行修改,在函数中对这个列表所做的任何修改都是永久性的,如下所示:

def print_models(unprinted_designs, completed_models): 
    """ 
    模拟打印每个设计,直到没有未打印的设计为止 
    打印每个设计后,都将其移到列表completed_models中 
    """ 
    while unprinted_designs: 
        current_design = unprinted_designs.pop() 
        # 模拟根据设计制作3D打印模型的过程 
        print("Printing model: " + current_design) 
        completed_models.append(current_design) 

def show_completed_models(completed_models): 
    """ 显示打印好的所有模型 """ 
    print("\nThe following models have been printed:") 
    for completed_model in completed_models: 
        print(completed_model) 

unprinted_designs = ['iphone case', 'robot pendant', 'dodecahedron'] 
completed_models = [] 

print_models(unprinted_designs, completed_models) 
show_completed_models(completed_models)

在上面这段代码中,向函数print_models()传入一个具有三个元素的列表unprinted_designs和一个空列表completed_models,在函数中将列表unprinted_designs中的元素依次弹出,再依次存储在空列表completed_models中,调用print_models()函数后,原本具有三个元素的列表unprinted_designs变为空列表,而原本为空列表的completed_models则倒序存储有unprinted_designs中的元素,其输出结果如下所示:

Printing model: dodecahedron
Printing model: robot pendant
Printing model: iphone case

The following models have been printed:
dodecahedron
robot pendant
iphone case

4.3 禁止函数修改列表(使用列表切片副本)

将原列表当作实参传入函数时,如果在函数对其进行修改,则该修改是不可逆的,如果想要将列表传入函数,又要原列表不发生变化,则可选择将列表的切片副本传入函数,这样既能得到传递原列表相同的结果,又能保证原列表不发生变化,其形式如下所示:

function_name(list_name[:])

5. 传递任意数量的实参

如果你预先不知道函数需要接受多少个实参,则可以采用下面的方法使函数能够传递任意数量的实参:

def make_pizza(*toppings): 
    """ 打印顾客点的所有配料 """ 
    print(toppings) 

make_pizza('pepperoni') 
make_pizza('mushrooms', 'green peppers', 'extra cheese')

形参名*toppings中的星号让Python创建一个名为toppings的空元组,并将收到的所有值都封装到这个元组中,其输出结果为:

('pepperoni',) 
('mushrooms', 'green peppers', 'extra cheese')

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

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

def make_pizza(size, *toppings): 
    """ 概述要制作的比萨 """ 
    print("\nMaking a " + str(size) + "-inch pizza with the following toppings:") 
    for topping in toppings: 
        print("- " + topping) 

make_pizza(16, 'pepperoni') 
make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')

基于上述函数定义,Python将收到的第一个值存储在形参size中,并将其他的所有值都存储在元组toppings中,其使出结果为:

Making a 16-inch pizza with the following toppings:
- pepperoni

Making a 12-inch pizza with the following toppings:
- mushrooms
- green peppers
- extra cheese

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

有时候,需要接受任意数量的实参,但预先不知道传递给函数的会是什么样的信息。在这种情况下,可将函数编写成能够接受任意数量的键值对,如下面的代码所示:

def build_profile(first, last, **user_info):
    """ 创建一个字典,其中包含我们知道的有关用户的一切 """
    profile = {}
    profile['first_name'] = first
    profile['last_name'] = last
    for key, value in user_info.items():
        profile[key] = value
    return profile

user_profile = build_profile('albert', 'einstein', location='princeton', field='physics')
print(user_profile)

函数build_profile()的定义要求提供名和姓,同时允许用户根据需要提供任意数量的名称—值对。形参**user_info中的两个星号让Python创建一个名为user_info的空字典,并将收到的所有名称—值对都封装到这个字典中。在这个函数中,可以像访问其他字典那样访问user_info中的名称—值对。

6. 将函数存储在模块中

函数的优点之一是使用它们可将代码与主程序分离。通过给函数指定描述性名称,可让主程序容易理解得多。进一步的,函数还可以存储在被称为模块的独立文件中,再将模块导入到主程序中。import语句允许再当前运行的程序文件中使用模块中的函数。导入模块的方法有很多种,下面将做一一介绍。

6.1 导入整个模块

要让函数是可导入的,得先创建模块。模块是扩展名为.py的文件,包含要导入到程序中的代码。下面来创建一个包含函数make_pizza()的模块,并将其保存在pizza.py中。

pizza.py

def make_pizza(size, *toppings): 
    """ 概述要制作的比萨 """ 
    print("\nMaking a " + str(size) + "-inch pizza with the following toppings:") 
    for topping in toppings: 
        print("- " + topping)

接下来,在pizza.py所在的目录中创建另一个名为making_pizzas.py的文件,这个文件导入刚创建的模块,再调用make_pizza()两次:

making_pizzas.py

import pizza 

pizza.make_pizza(16, 'pepperoni') 
pizza.make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')

Python读取这个文件时,代码行import pizza让Python打开文件pizza.py,并将其中所有的函数都复制到这个程序中。你看不到复制的代码,因为这个程序运行时,Python再幕后复制这些代码,你只需要知道,在making_pizza.py中,可以使用pizza.py中定义的所有函数。要调用被导入的模块中的函数,可指定导入的模块的名称pizza和函 数名make_pizza(),并用句点分隔它们。这些代码的输出与没有导入模块的原始程序相同:

Making a 16-inch pizza with the following toppings:
- pepperoni

Making a 12-inch pizza with the following toppings:
- mushrooms
- green peppers
- extra cheese

6.2 导入特定的函数

还可以导入模块中的特定函数,这种导入方法的语法如下:

from module_name import function_name

通过用逗号分隔函数名,还可根据需要从模块中导入任意数量的函数:

from module_name import function_0, function_1, function_2

对于前面的making_pizzas.py示例,如果只想导入要使用的函数,代码将类似于下面这样:

from pizza import make_pizza 

make_pizza(16, 'pepperoni') 
make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')

若使用这种语法,调用函数时就无需使用句点。由于我们在import语句中显式地导入了函数make_pizza(),因此调用它时只需指定其名称。

6.3 使用as给函数指定别名

如果要导入的函数的名称可能与程序中现有的名称冲突,或者函数的名称太长,可将函数指定为另一个好辨识的别名,如下所示:

from pizza import make_pizza as mp 

mp(16, 'pepperoni') 
mp(12, 'mushrooms', 'green peppers', 'extra cheese')

在上面的代码中,将函数make_pizza()指定了别名mp(),这样在调用它时就只需用其别名即可。

6.4 使用as给模块指定别名

除了给函数指定别名外,还可以给模块指定别名,如下所示:

import pizza as p 
p.make_pizza(16, 'pepperoni') 
p.make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')

6.5 导入模块中的所有函数

使用星号(*)运算符可让Python导入模块中的所有函数:

from pizza import * 

make_pizza(16, 'pepperoni') 
make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')

当然在使用并非自己编写的大型模块时,不建议使用这种导入方法,它很可能会导致多个函数名称相同,从而互相覆盖的问题,正确的做法是,要么只导入你需要使用的函数,要么导入整个模块并使用句点表示法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

秋风、萧瑟

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

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

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

打赏作者

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

抵扣说明:

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

余额充值