Python小白入门:第七讲|


Python小白入门:第七讲||函数

当你需要在程序中多次执行同一项任务时,你不需要反复编写该任务的代码
而只需要编写一个函数,每次需要执行任务时调用它即可。

在这一讲中,你将学习:

  • 如何编写函数,以及如何传递实参,让函数能够访问完成其工作所需的信息;
  • 如何使用位置实参和关键字实参,以及如何接受任意数量的实参;
  • 显示输出的函数和返回值的函数;
  • 如何将函数同列表、字典、if 语句和while 循环结合起来使用。
  • 如何将函数存储在被称为模块的独立文件中,让程序文件更简单、更易于理解。
  • 函数编写指南,遵循这些指南可让程序始终结构良好,并对你和其他人来说易于阅读。

7.1 如何定义一个函数

<code>def greet():
"""打印hello"""

print("hello")
greet()/<code>

第一行代码使用关键字def指明你所定义的函数的名称(greet),这是定义函数。注意冒号

第二行代码是一个文档字符串,指出函数的作用,你可以对函数进行描述,方便以后使用。

第三行代码是函数的主体部分,你可以使用缩进来继续扩展函数。

第四行代码进行函数的调用,你每次需要使用函数时都需要调用一次

<code># 输出
hello/<code>

你还可以向函数传递信息,只需要在函数后面的括号中指定一个参数,这个参数用来接收你传递的任何值

然后在调用的时候将另一个参数传递给函数,这个参数是一个具体的值。

<code>def greet(name):
"""打印hello"""
print("hello" + name.title())
greet('qimu')/<code>

函数名后面的参数name是一个形参——函数完成其工作所需的一项信息

调用函数时 ‘qimu’是一个实参——调用函数时传递给函数的信息

简而言之,在greet('qimu')中,将实参'qimu'传递给了函数greet(),这个值被存储在形参name中

7.2 传递实参

鉴于函数定义中可能包含多个形参,因此函数调用中也可能包含多个实参。

如何向函数传递实参呢?

7.2.1 位置实参——这要求实参的顺序和形参的顺序一样

<code>def name(my_name, his_name):
print("my name is" + my_name.title())
print("his name is" + his_name.title())
name('qimu', 'jack')/<code>

这里有两个形参,myname和his_name

也有两个实参 'qimu'和'jack'

需要注意的是 形参和实参必须一一对应,因为my_name只能是qimu,这就是位置实参

需要执行多少次任务就调用函数多少次,只需要每次向函数传递所需的实参即可

7.2.2 关键字实参——传递给函数的名称—值对

简言之,就是在实参中将名称和值关联起来。

关键字实参无需考虑函数调用过程中的实参顺序。

<code>def name(my_name, his_name):
print("my name is" + my_name.title())
print("his name is" + his_name.title())
name(my_name = 'qimu', his_name = 'jack')/<code>

my_name ='qimu'和his_name ='jack'可以换顺序,并不影响程序的运行结果

7.2.3 默认值

编写函数时,可以给每个形参指定默认值。

在函数调用过程中给形参提供了实参时,python将使用指定的实参值。否则,使用默认值

<code>def name(my_name, his_name = 'jack'):
print("my name is" + my_name.title())
print("his name is" + his_name.title())
name(my_name = 'qimu')/<code>

7.2.4 等效的函数调用

鉴于可以混合使用位置实参、关键字实参和默认值,通常有多种等效的函数调用方式

<code>def name(my_name, his_name = 'jack'):
print("my name is" + my_name.title())
print("his name is" + his_name.title())
name(my_name = 'qimu')
name('qimu')
name('qimu', 'tom')
name(my_name = 'qimu', his_name = 'tom')
name(his_name = 'tom', my_name = 'qimu')/<code>

上述几种函数调用方式都是等效的

在调用函数时,要避免实参错误,如果忘记给函数传递实参,python会给你指出这一错误

7.3 返回值

7.3.1 返回简单值

函数并非总是直接显示输出,它可以处理一些数据,并返回一个或一组值

函数返回的值被称为返回值

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

my_name = get_formatted_name('qi', 'mu')
print(my_name)/<code>

函数get_formatted_name()的定义通过形参就受名和姓。

他将名和姓合二为一,在他们之间加上一个空格,并将结果存储在变量full_name中

调用返回值的函数时,需要提供一个变量,用于存储返回的值(my_name)

7.3.2 让实参变成可选的

假如调用函数时无论传递两个,还是三个实参,函数都能处理

<code>def get_formatted_name(first_name, middle_name = ' ', last_name)
"""返回整洁的姓名"""
if middle_name:
full_name = first_name + ' ' + middle_name + ' ' + last_name

else:
full_name = first_name + ' ' + last_name
return full_name.title()

my_name = get_formatted_name('qi', 'mu')
print(my_name)

my_name = get_formatted_name('qi', 'middle', 'mu')
print(my_name)/<code>

注意并非所有人都有中间名,如果你调用这个函数时只提供了名和姓,他将不能正确的运行。

为了让中间名变成可选的,可给形参middle_name 指定一个默认值——空字符串,并在用户没有提供中间名时不使用这个形参。

7.3.3 返回字典

函数可以返回任何类型的值,包括列表和字典等复杂的数据结构

<code>def get_formatted_name(first_name, last_name)
"""返回一个字典,其中包含一个人的信息"""
name = {'first': first_name, 'last':last_name}
return name

my_name = get_formatted_name('qi', 'mu')
print(my_name)/<code>

函数接受名和姓,并将这些值封装到字典中

存储first_name的值时,使用的键为'first',而存储last_name时,使用的键为'last'。

你还可以在函数中添加一个参数age表示年龄:

<code>def get_formatted_name(first_name, last_name, age=' ')
"""返回一个字典,其中包含一个人的信息"""
name = {'first': first_name, 'last':last_name}
if age:
name['age'] = age
return name

my_name = get_formatted_name('qi', 'mu', age=27)
print(my_name)/<code>

其中age是一个可选的形参,将其默认值设置为空字符串。

7.3 传递列表

为什么要传递列表呢?

将列表传递给函数后,函数就能直接访问其内容。

<code>def greet(names):
"""向每个人打招呼"""
for name in names:
message = "hello" + name.title()
print(message)

users_name = ['qimu', 'jack', 'tom']
greet(users_name)/<code>

函数接受一个名字列表,并将其存储在形参names中。

一旦列表传递给了函数,函数就可以对其进行修改(添加,删除,替换),而且这个修改时永久性的。

有时候,我们也需要禁止函数修改列表,因为一旦函数修改了列表,原先的列表就无法保留了。所以我们可以向函数传递副本而不是原件。

切片表示法来创建列表的副本

<code>function_name(list_name[:])/<code>

7.5 传递任意数量的实参

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

<code>def name(*names)
"""打招呼"""
print("hello" + name.title())

name('qimu')
name('qimu', 'jack', 'tom', 'alien')/<code>

形参名*name中的星号让Python创建一个名为name的空元组,并将收到的所有值都封装到这个元组中。

不管收到一个还是三个名字,函数都能妥善处理。

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

如果要让函数接受不同类型的实参,必须在函数定义中将接纳任意数量的实参放在形参最后。

Python先匹配位置实参和关键字实参,再将余下的实参都收集到最后一个形参中。

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

有时候需要接受任意数量的实参,但预先不知道传递给函数的会是什么样的信息。在这种情况下,可将函数编写成能够接受任意数量的键值对——调用语句提供多少就接受多少。

<code>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',
filed='physics')
print(user_profile)/<code>

形参**user_info中两个星号让Python创建一个名为user_info的空字典

7.6 将函数存储在模块中

函数的优点之一是,使用他们可将代码块与主程序分开。

可以进一步,将函数存储在被称为 模块 的独立文件中,再将模块导入到主程序中。

import语句允许在当前运行的程序文件中使用模块中的代码。

7.6.1 导入整个模块

要想让函数是可导入的,得先创建模块。

模块是扩展名为.py的文件,其中包含了函数代码。

<code># 需要调用函数时
import module_name

module_name.function_name()/<code>

只需遵循上述语法即可完美调用模块

7.6.2 导入特定的函数

可以导入模块中特定的函数

<code>from module_name import function_name
from module_name import function_0, function_1, function_2/<code>

7.6.3 使用as给函数指定别名

导入的函数名可能与程序中现有的名称冲突,或者函数名太长,可指定独一无二的别名。

<code>from module_name import function_name as fn/<code>

这里fn随便啥都可以,但要符合命名规则

7.6.3 使用as给模块指定别名

<code>import module_name as fn/<code>

7.6.4 导入模块中所有函数

使用星号可让Python导入模块中所有函数

<code>from module_name import */<code>


分享到:


相關文章: