0%

Python - 关于函数的学习

函数的定义

函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。

出自 菜鸟教程

定义函数

定义一个函数需要使用关键词 def,关键词后需要跟函数的名称和可能会包含参数的括号,以及一个冒号。然后换行打出一个制表符,然后输入需要执行的代码段。

例 1:

1
2
3
4
5
6
7
8
9
10
11
def hello():
"""显示简单的问候语。"""
print('Hello!')

# 函数中使用三个引号包围的是对函数的注释,也称文档字符串。文档字符串用于描述函数的作用,Python 会使用它们来生成有关程序中函数的文档。
# 想要调用这个函数的时候只需要输入这个函数的名称即可:

hello()

# 函数执行后得到的结果。
# Hello!

向函数传递信息

形参的定义

形参是指形式上的参数,在为其赋值时没有实际值的,在函数中的形式可以理解为一个变量。形式参数的作用是以变量的形式来传递当前位置的值。

实参的定义

实参是值有具体值的参数,可以是字符串或数字。

形参转实参

形参和实参的界定标准就是,该变量在当前是否传递具体值。

例 2:

1
2
3
def fuc(a, b):
c = a + b
return c

对于此例来说,定义函数时 a 是形参,调用函数时 a 是实参。一旦定义了形参,在调用函数时必须给形参赋值并且实参化,否则程序会报错,无法正常运行。

形参、实参的定义以及形参转实参的说明参考 知乎 - 一文看懂 python 函数形参与实参的区别及应用

传递实参的方法

1、想要像函数中传递实参可以使用:位置实参,这要求实参的顺序和形参的顺序相同;关键字实参,这要求传递给函数的是一组键值对,可以使用列表和字典。

例 3:

1
2
3
4
5
6
7
8
9
# 位置实参
def OwO(i, l):
print(f'i = ${i}, l = ${l}')
OwO(l, i) # 对于位置实参来说,实参的顺序非常重要,如果实参的位置不对,可能会导致函数执行时出现意想不到的情况。

# 关键字实参
def QAQ(i, l)
print(f'i = ${i}, l = ${l}')
OwO(i='i', l='l') # 关键字实参不需要在意输入的顺序,因为关键字实参直接对形参指定了对应的实参。

2、当在创建函数时对其中的形参指定了一个值之后,Python 将会将这个指作为默认值,当这个形参没有被实参化的时候,这个形参将直接使用默认值作为实参。

例 4:

1
2
def OwO(i, l='l')
print(f'i = ${i}, l = ${l}')

执行例 4 中的函数,当我们没有给形参 l 实参化时,Python 会直接指定 ‘l’ 为 l 的实参。

3、在函数中加入 if 语句,可以使函数中的部分形参的实参化变成可选的。

1
2
3
4
5
def OwO(i, j=''):
if j = '':
print(f'${i}')
else:
print(f'${j} + ${i}')

为一个形参设置默认值,当这个形参没有被赋予任何实参的时候,函数中的 if 语句会选择执行相应的语句,这样便可以达到使部分形参的实参化变得可选。

向函数传递列表

将列表传递给函数之后,函数就能够直接访问列表中的内容,可以使用函数来处理列表中的内容。

例 5:

1
2
3
def hello(names):
for name in names:
pring(f'Hello, ${name}.')

例 5 中的函数会在得到一个列表之后,将列表遍历,然后问候列表中的每个储存的人名。

使用函数处理列表

将列表传递给函数之后,函数将能够更改列表中的值。

例 6:

1
2
3
4
def name(names):
temp = names.pop()
print(temp)
recorded_names.append(temp)

创建一个副本使函数不处理列表本体

当我们的需求是不改变列表本身的元素的时候,可以创建一个列表的副本并传递给函数。

例 7:

1
2
3
4
5
6
def name(names):
temp = names.pop()
print(temp)
recorded_names.append(temp)
names = ['OwO', 'w']
name(names[:])

如例 7 中将列表的副本传递给函数,函数便不会更改列表的本体的信息。

函数的返回值

返回简单的值

函数可以处理一些数据并返回运行结果。

例 8:

1
2
3
def OwO(i, j):
x = i + j
return x

例 8 中的函数在得到传递的实参之后,便按照事先设置好的语句将两个实参相加并且赋值给变量 x,然后返回值 x。

返回字典和将函数与 while 循环结合

函数可以返回任何类型的值,包括字典。

列 9:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
def Name_list(FN, LN, age=None):
if age:
Name = {'first name': FN, 'last name': LN, 'age': age}
Name = {'first name': FN, 'last name': LN}
return Name
people = []
number = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
while True:
print("If you need to exit the loop, please enter \"q\".")
FN = input("Please enter your first name:\n")
if FN == 'q':
break
LN = input("Please enter your last name:\n")
if LN == 'q':
break
age = input("Please enter your age:\n")
if list(set(age)) not in number:
print('Please enter number. This input will not be entered into the \
list.')
continue
elif age == 'q':
break
people.append(Name_list(FN, LN, age))
print(people)

例 9 中设置了一个函数用来收集一个人的姓名和年龄然后制作成一个字典,并且将字典放回,后面的函数则是用户输入以及让用户选择什么时候退出的功能的实现。

传递任意数量的实参

如何传递任意数量的实参

例 10:

1
2
3
def OwO(*owos):
for owo in owos:
print(owo)

*owos 会让 Python 生成一个名为 owos 的空元组,向函数传递了多少函数就会全部录入到元组。

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

同时使用位置实参和任意数量实参时,需要将接收人数数量实参的形参放到最靠后的位置,且此种形参只能有一个。

例 11:

1
2
3
4
def OwO(qaq, *owos):
print(qaq)
for owo in owos:
print(f"- ${owo}")

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

如果需要多个位置获取多个数值,可以设置多个可以获取任意数量实参的形参。

例 12:

1
2
3
4
5
6
7
def OwO(*owos, *qaqs):
print("owos list:")
for owo in owos:
print(f' - ${owo}')
print('qaqs list:')
for qaq in qaqs:
print(f' - ${owo}')

如果需要传递任意数量的实参,但是又不清楚需要传递的实参属于什么信息时,可以先设置已知确定的类型(非形参。),然后设置一个可以获得人数数量实参的形参。

例 13:

1
2
3
4
5
def OwO(owo, **qaqs):
qaqs['自己设置的名称'] = owo
return qaqs
Owo = OwO('owo', az = 'az', tz = 'tz')
print(Owo)

模块

函数可以被储存在叫 模块 的文件中。模块可以让函数更加灵活的被使用,如果在多个地方需要使用同一个函数,可以直接导入这个模块,而不需要在代码中重新写一遍函数。

导入整个模块

模块是扩展名为 .py 的文件,将函数写进这个文件,即可直接使用 import 直接导入。当我在模块文件中写下了例 13 中的函数,并且将模块文件放到需要使用例 13 中的函数的 python 脚本同级的目录中,即可直接按照例 14 中的方法使用例 13 中的函数。

例 14:

1
2
3
4
5
6
# 假设模块文件名为“dictionary.py”。
import dictionary
QAQ = dictionary.OwO('OwO', owo='owo', qwq='qwq')

# 输出:
# {'owq': 'owo', 'qwq': 'qwq', '自己设置的名称': 'OwO'}

导入特定的函数

从一个模块中直接导入一个函数,可以使此函数直接在代码中被使用,而不需要引用模块的名。
导入模块中特定的函数的格式是:

1
from moudle_name import function_name

可以导入一个模块中的多个函数,格式如下:

1
from moudle_name import function_1, function_2, function_3

导入特定的函数之后就能直接在代码中使用这个函数而不引用模块的名字,如例 15。

例 15:

1
2
from dictionary import OwO
QAQ = OwO('OwO', owo='owo', qwq='qwq')

使用关键字 as 给函数指定别名

当需要给一个模块中的函数指定另一个名称时(函数名字过长、导入函数中的名字与代码中现有的名称冲突),可以使用关键字 as 给函数指定一个 独一无二的别名

例 16:

1
2
3
from dictionary import OwO as o

QAQ = o('OwO', owo='owo', qwq='qwq')

当引入了一个模块,为这个模块的一个函数指定别名之后便可直接使用别名调用这个函数。

使用关键字 as 为模块指定别名

as 关键字不知可以为函数指定别名,也可以为模块指定别名。as 为模块指定别名的方法一般用于简化模块名称,方便调用函数。

例 17:

1
2
3
from dictionary as d

QAQ = d.OwO('OwO', owo='owo', qwq='qwq')

导入模块中所有的函数

导入模块中所有的函数时,调用函数时将不再需要引用模块名。

例 18:

1
2
3
4
from OwO import *

owq('1', '2')
pwo('3','4')

如果在编写大型模块,不推荐使用此方法,如果模块中有函数的名称和代码中使用的名称是相同的话,会出现意外的情况。便携大型模块的时候推荐使用句点表示法,或者只导入自己需要的函数。

编写函数时应该注意的事情

  1. 当你为函数的形参指定默认值的时候,请不要让“=”两边出现空格。当调用函数的时候使用关键字实参的时候,也应该这样;
  2. PEP 8 建议代码行的长度不要超过 79 个字符,这样的话,只要编辑器窗口适中,就能够看见整行代码,如果形参很多,导致函数定义的长度超过了 79 个字符,可以在函数定义中输入左括号并且回车并在下一行按两次 Tab 键,使形参列表和只缩进一层的函数体分开,如例 19;
  3. 如果程序或者模块包含多个函数,可以用两个空行将相邻的函数分割开来,这样更好分辨不同的函数;
  4. 几乎所有的 improt 语句都应该放在代码的开头,唯一例外的情况是在代码开头使用了注释来说明代码的用途。

例 19:

1
2
3
4
def function_name(
parameter_0, parameter_1, parameter_3,
parameter_4, parameter_5, parameter_6):
function body

欢迎关注我的其它发布渠道