一直在啃英文原版的Python Crash Course(2nd),进度比较缓慢,但还是要“墙裂”推荐这本书,而且最好看原版,写得非常简单易懂。关于如何下载高清原版英文书,请参考我之前的文章:高清英文原版书籍下载网站。这篇笔记是这本书里第8章的部分内容,关于Function(函数)的。简单直接的告诉python小白们:什么是function,以及它的结构和用法。
在读别人的python代码的时候,经常会看到一个一个的function。那么问题来了:
什么是function?
Function用最直白的话说就是你要执行的一个特定的task(命令)。你可以把这个特定的命令写到blocks of code(代码块)里。(实际上我觉得function有点像linux里的脚本,我们一般把命令写在脚本里,然后直接运行脚本就行了。而在python里,调用的过程就是call function)
(一)定义一个Function
首先,先看一下如何定义一个function。这有一个最简单的例子:
def greet_user():
"""Display a simple greeting."""
print("Hello!")
greet_user()
这个例子展示了一个最最最简单的function的结构:
第一行:使用def来告诉python我要定义一个function了。这一步叫做“function definition”。这一步的作用是告诉python这个function 的名字,并告诉python是否需要必要的信息来执行这个function。括号里的就是必要的信息。在这个例子里,我们定义的function名字叫greet_user()
,它不需要另外的信息来执行,所以括号里是空的。定义function的最后要以冒号“:”结束。
定义了一个function后,第二行起就要缩进了。第二行用三对引号括起来的叫做“docstring”, 描述了function是干什么的。也就是我们通常说的的“comment”。
第三行print("Hello!")
实际上才是function真正要执行的代码。因为这个function是一个最简单的例子,所以我们只执行打印出Hello! 到这里,我们的function也就结束了。
当你想使用这个function的时候,你需要call it。call function就是告诉python我要执行这个task。在执行这个function的时候,你需要它的名字greet_user
,以及必要的信息,使用()
来提供,所以当你call这个function,会输出:
Hello!
(1)给function传递信息
把上面的代码稍稍改一下,让greet_user()
function不止输出Hello! 而且要输出名字。为了达到这个目的,你需要在定义function的时候在括号里输入username。通过添加username,允许function接收任何你指定的username值。这时,当你每次call这个function的时候,就要在括号里输入必要的信息了:
def greet_user(username): #这里的括号中添加了username这个参数
"""Display a simple greeting."""
print(f"Hello,{username.title()}!")
greet_user("jesse") #call function的时候也要加上一个指定值,“jesse”就是你在call function的时候要加上的必要信息
Hello,Jesse!
(2)变量和参数(Arguments and Parameters)
在前面的greet_user()
function中,我们定义了greet_user()
要求变量username的值。一旦我们调用该函数并向其提供信息(人名),它就会打印正确的问候语。greet_user()
定义中的变量username是一个参数示例,它是函数执行任务所需的信息。greet_user('jesse')
中的值'jesse'是一个参数的例子。参数是在调用函数时传递给函数的一段信息。当调用函数时,我们把希望函数使用的值放在圆括号中。在本例中,参数'jesse'被传递给函数greet_user()
,值被分配给参数username。
NOTE:人们有时把变量和参数混为一谈。如果看到函数定义中的variables被称为“变量(Arguments)”,或者函数调用中的variables被称为“参数(Parameters)”,请不要感到惊讶。
(二)传递变量(Arguments)
因为函数定义可以有多个参数,所以函数调用可能需要多个变量。你可以通过多种方式向函数传递参数。比如:你可以使用位置变量(使用相同的顺序写参数);也可以使用关键字变量,其中每个变量由一个变量名和一个值组成;也可以使用列表和字典。
(1)位置变量
当你call一个function的时候,python必须匹配每function call和funciton定义里的每一个变量。最简单的做法就是根据出现的顺序来匹配。举个例子:
def describe_pet(animal_type, pet_name):
"""Display information about a pet."""
print(f"\nI have a {animal_type}.")
print(f"My {animal_type}'s name is {pet_name.title()}.")
describe_pet('hamster', 'harry')
I have a hamster.
My hamster's name is Harry.
这个我们定义的function里需要两个信息:动物类型,动物名字。当我们call 这个function的时候,我们需要按照顺序提供动物的类型和名字。在这个例子里,'hamster'就被分配到动物类型参数里,而'harry'被分配到动物名字参数里。你可以试着把describe_pet('hamster', 'harry')
里的两个信息顺序交换一下,看看得到的是什么结果。
(2)关键字变量
关键字变量是传递给函数的名-值对。可以在变量中直接关联名称和值,这样在将变量传递给函数时就不会产生混淆。关键字变量使你不必担心在函数调用中错误地排序参数,它们明确了函数调用中每个值的作用。还用上面的例子来说明:
def describe_pet(animal_type, pet_name):
"""Display information about a pet."""
print(f"\nI have a {animal_type}.")
print(f"My {animal_type}'s name is {pet_name.title()}.")
describe_pet(animal_type='hamster', pet_name='harry') #只有在call function的时候代码不一样
(3)默认值
在编写function时,可以为每个参数定义一个默认值。如果函数调用中提供了参数的值,Python使用这个指定的值。如果不是,则使用参数的默认值。因此,当为参数定义默认值时,可以排除通常在函数调用中写入的相应参数值。使用默认值可以简化函数调用。
例如,如果你注意到大多数对descripbe_pet()的调用都用于描述dog,那么你可以将animal_type的默认值设置为'dog':
def describe_pet(pet_name, animal_type='dog'): #在定义function的时候就把animal_type定义为dog,后面call的时候就不用再指定特殊值了。但是这时要注意参数出现的顺序。
"""Display information about a pet."""
print(f"\nI have a {animal_type}.")
print(f"My {animal_type}'s name is {pet_name.title()}.")
describe_pet(pet_name='willie') #这里只需指定pet_name的值
(4)避免变量错误
如果你在call function的时候,少传递了必要的信息,比如说上面的例子,你在Call function的时候只写了:
describe_pet()
那么就会出现下面的报错:
TypeError Traceback (most recent call last)
in
4 print(f"My {animal_type}'s name is {pet_name.title()}.")
5
----> 6 describe_pet() #这个箭头告诉我们问题出现的位置
TypeError: describe_pet() missing 1 required positional argument: 'pet_name' #这里告诉我们具体是什么问题导致报错,这里可以看出来是缺失了1个必要的变量
笔记很短,只是记录并分享一下function的最基本的结构和功能。更多细节还需要看书来学习。