03 – Python101 – 自己写函数(Functions)

本篇文章包含代码段落,建议使用电脑浏览器查看或使用手机浏览器“桌面网页”模式。

在编程里,我们想要程序执行一定的功能除了直接输入一行行命令以外,也可以通过函数实现。函数构成了程序运行的基础。

在Python中,所有的命令都是函数所构成的。比如我们在执行:a = 1 + 2 时,我们实际上调用了python自带 Operater 包中 __add__ 这个函数。我们输入函数的两个 参数(parameter) 分别为1,2,__add__(1, 2) 函数返回值为 3,因此最终 a 获得赋值 3。Python为了用户使用方便,把这些函数简化成了我们常见的数学符号。人们所常说的python包,python库也都指的是社区各位作者编辑好的函数的集合。

在很多时候,除了python以及各个包里给我们提供的函数,我们仍需要程序能够执行一些我们想要的功能。如果我们仅仅使用一行行命令去执行,便会造成冗长的代码,对于后期修改造成极大困难。同时,在我们需要反复执行某个命令的时候,直接使用命令也会产生大量重复内容。

这时,我们可以自己定义函数。在定义函数的时候, 为了保证以后程序维护(修改,检查,debug等)的方便,我们会尽可能让他们的格式统一。

自定义函数

在Python中,当我们需要自定义一个函数并执行,我们只需要在代码中编辑:

def name(input):
    <function body>   #注释:由各种命令组成
    return output

print(name(1))

def 表示我们在定义一个函数,name是函数名,括号中的内容input表示函数所需要输入的参数,表示这个函数所执行的代码从此开始;

通过以上的代码,我们可以定义一个名叫name,需要一个输入变量,返回一个变量的自定义函数。它会执行<function body>部分所要求的内容,并在执行完毕后返回1。在python中,函数,if 等 分heading,body的语句都用制表符(4个空格,或一个缩进/indent)进行分割,像函数中,函数中的内容会与函数外的内容有一个indent的差距。因此,在python编程中,缩进(indent)和空格的数量非常重要。

然而,当我们看到这样一个函数,不结合定义函数时的想法,我们无法知道这个函数能做什么,也不知道这个函数所需要什么样类型的input,我们甚至不知道这个函数会导致我们的输入值发生什么样的改变,会返回什么类型的值。

假设我们所需要的是一个将输入的数字乘方的函数,那我们可以把函数拓展一下:

01. def square(input_variable_name:int) -> int:
02.     """<三个单引号表示长段注释,可以换行那种>
03.     Return the square of input_value.
04.     
05.     (可选)precondition:~~~~
06. 
07.     >>> square(2)
08.     4
09.     >>> square(3)
10.     9
11.      
12.     """
13.      
14.     <function body>   
15.     #由各种命令组成的函数内容
16.     return output

上一段中,改变的部分我都用加粗字体标出。具体的改动及目的如下:

第1行中,我们把函数名name改成了square。这样,当这个函数在后文中被提及时,我们也可以判断出这个函数大概的用途;除此之外,我们使用: int以及 -> int 表示了这个函数输入变量和输出变量的类型。其中 input_value: int 表示square函数 input_value 这个parameter(又称形参)所需要的类型,而 -> int 表示这个函数输出值默认会是一个int。注意:这里的两个int都只是用于提醒自己,而Python不会检查输入值和输出值是否符合这里的规定。即使我们在定义的时候标注了输入值和输出值的类型,你输入其他类型变量时这个函数仍然会运行,至于结果对不对,那就不一定了。 😀

“””Docstring”””

第2 ~ 12行 “”” “”” 所包含的内容是长段注释,叫做doctring,包含了我们对于这个函数的描述。Docstring在保持函数整洁,以及提高程序易读性上非常有用。

第2,3行中,我们描述函数的用处,此处一般用英文因为编程中英文是更加通用的语言。这个描述里,我们应该点名输入变量的名称(input_value),输出什么样的东西(Return sth,如果函数没有输出则不需要这一部分)。

第5行中,我们可以写这个函数的输入变量的要求,比如输入值必须大于0,必须能够被2整除,长度不为0(对于列表,str等类型)等等。对于一些只在某一个特定程序才会用到的函数,我们也可以包含输入值和其他没输入的变量的关系。如果没有则不用专门说明。

第7 ~ 9行是doctest。这是Python特有的一个功能。由它的命名可知,这是“docstring”中的”test”。Python会自动检查doctest,并且执行所有 >>> 之后的语句,检查是否于它下方的输出相匹配。这是一个非常快捷的检查自定义函数是否能正常运行的方式,一般我们会包含一到两个doctest。

其他就是和一般函数一样的的内容啦,写下函数的具体算法,包含或不包含返回值,写完之后,这就是一个既好用,又好看的标准的函数啦。

练习

尝试一下,给你以下的函数,你能看出哪一个是函数的正确用法吗?

def GetCurvedMark(student:str) -> int:
    """Return the curved mark of the student provided.

    Precondition: student is in student_list.
 
    >>> GetCurvedMark("Amy")
    65

    """
    <Mystery Code that works according to Docstring>
    return output

Amy = 65
Jack = 50
Bill = 77
Martin = 90
student_list = ["Amy","Jack","Bill"]


# 哪个是函数正确的用法?
    a. print(GetCurvedMark("Martin"))
    b. print(GetCurvedMark("Bill"))
    c. GetCurvedMark("Amy").pop()
    d. print(GetCurvedMark(Amy))

鼠标悬浮到方块上获得答案:

解析:

a – 这个函数命令的input类型,output类型的使用都是正确的。但 “Martin” 并不在student_list中,把它作为 input 也许可以执行,但它并不属于这个函数所负责的范围。用数学的话来说,“Martin” 并不属于这个函数的定义域

b – 符合input,output类型,“Bill” 也在student_list中,返回的值时int可以作为print语句的输入值,因此是正确的。

c – 符合input,output类型,“Amy” 也在student_list中,但GetCurvedMark函数返回的值是int,并不支持.pop() 这个函数,所以会报错。

d – Amy是一个类型为int的变量,在前文中被定义过 Amy = 65。GetCurvedMark需要我们输入的是一个str,而不是int。

最后一点点唠嗑 ~

在编程中,最重要的从来不是某一个语言的语法或者内存的调用方法。这些客观的、被人发明的东西都是可以在网络上搜索到的。最重要的是写程序时的算法思维以及协作思维。当我们在创建自己的函数或者类(这个以后会讲到)的时候,养成整理代码,写好注释及范例的习惯也是在提高我们的协作能力。有一个故事是这么理解的:盲人在黑夜打灯为的是让别人不误撞到自己。写美观的程序也是一样,看上去是在方便别人,但最终当别人需要和你协同修改你的程序,你就可以随时知道这个程序在哪负责哪个功能,可以被怎么修改,而不是需要从头到尾一条命令一条命令地看,方便的还是自己。

Coding is never about typing but Logic.

以上便是关于python自定函数的所有内容,希望这样的讲解能够帮助到正在学习这里,尚有困惑的朋友们。

本文由JamesChenS编写,未经授权禁止转载,可以外链哦 ~

Scroll to Top