2 方法/函数(Function)

2.1 方法

在数学上,有映射$f: A \to B$,如果在$A$中的元素$x$有唯一对应的$y \in B$,那么称$f$为函数(Function)。在计算机中的函数称为方法或函数,并且$A$是一个向量空间,即$\newcommand{\P}{\mathbb{P}} \newcommand{\d}{\text{d}} \renewcommand{\R}{\mathbb{R}} \newcommand{\N}{\mathbb{N}} \newcommand{\Z}{\mathbb{Z}}\newcommand{\b}{\boldsymbol}$$\b x \in A$,其中$\b x$是$n$维向量,即

\[y = f(x_1, x_2, ..., x_n)\]

但是,在计算机中,方法可以

  1. 没有输入(自变量),即$y = f()$。这样的函数也可以叫做过程(Procedure)。
  2. 没有输出,即$f(\b x) = NULL$。


2.2 在python中定义方法

在python中定义方法很简单。方法能有自己的名字,任取,在这里我选择method_name(注意,单词之间用下划线是python的命名惯例(Convention))。那么,定义的第一行是

def method_name():
    # otherthings

在这里,标记#之后的内容都是被编译器忽略的,叫做注释(Comments)。在这里,有效的只有第一行,即定义了一个方法,名称为method_name,没有参数(输入/自变量)。假设我想要这个方法实现:$f(x,y) = 5x + 6y$。那么,应该写作

def method_name(x, y):
    return 5 * x + 6 * y

其中,return称为返回语句,将后面的值返回xy称为参数,是传入这个方法的值。

注意,python是强格式语言,需要注意每个段落的缩进。如果没有缩进,就是与这个方法相同层级,即不在这个方法中。

方法能做的事不仅这些,还能

def print_smth():
    print("Hi")
    return

在这里,return不返回任何东西,默认返回没有东西,在python中称为None。如果方法不返回任何东西,那么return语句可以省略。在这里,这个方法执行了一些语句,所以它是一个过程,用于减少重复使用的代码量。


2.3 方法使用

使用方法称为方法的调用(Call),假设你像前面那样定义了方法method_name,那么可以这么调用:

>>> method_name(4, 5)
50

打印的值是方法的返回值。你能将返回值赋值给其它变量:

>>> a = 4
>>> b = 5
>>> a = method_name(a, b)
>>> a
50

现在a存储了运算的结果,即50。

之前的print_smth也一样:

>>> print_smth()
Hi

但是如果赋值呢?

>>> a = print_smth()
Hi
>>> a

你会发现a什么都没有,如果用print去打印它呢?

>>> print(a)
None

它是None


2.4 进阶:方法也是变量

本节以及之后的内容适合经验者

变量能赋值变为方法类型,事实上是赋值了同一个指针:

>>> method_name
<function method_name at 0xbeefcafe>
>>> a = method_name
>>> a
<function method_name at 0xbeefcafe>

于是也能调用它

>>> a(4, 5)
50

那么,既然它像是变量,所以又能以参数的形式传递给另一个函数:

>>> def call_that(func):
...     func()
...
>>> call_that(print_smth)
Hi

所以,引入一个更加方便的写函数的语句,称为lambda语句,格式为:

lambda x, y: 5 * x + 6 * y

这个方法等同于刚才的method_name。唯一的不同在于它现在是匿名的,可以赋值给变量,或者当做参数传递。很可惜,在python中,lambda表达式用处并不是那么大,但是在其它语言中,它是一个很好的语法糖。