Python中定义Function(函数)

Function(函数),也可称为方法是用于组织单个相关操作的、可重用的代码块。

Python为您提供了许多内置函数,例如print()等,但您也可以创建自己的函数。 这些函数称为用户定义函数

如下例所示,定义了一个打印小于n的斐波那契数列的函数:

def fib(n):    
    """打印小于n的斐波那契数列"""
    a, b = 0, 1
    list=[]
    while a < n:
        list.append(a)
        a, b = b, a+b
    return list

调用如上的函数,将输出如下结果:

>>> fib(10000)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765

定义函数有以下规则:

  • 函数以关键字def开头,后跟函数名称和括号(())包围的参数表,如上例为(n)
  • 参数表包括调用函数所需的参数,这里定义的参数称为形参,如上例的n调用函数(fib(10000))时传递的参数10000称为实参
  • 每个函数中的代码块都以冒号(:)开头并缩进。
  • 函数的第一个语句是可选语句——函数的文档字符串,可用于生成文档。
  • 语句return list退出函数,将list传回给调用者。 不带参数的return语句与 return None相同。

不同于其它语言,Python没有函数和过程的区别。(函数有返回值,过程没有。)事实上,Pathon中即使没有return语句的函数也会返回None,尽管它没有什么用。 该值称为。 如果你想使用print()把它打印出来,你可以看到它:

 def noreturn(str):
     print(str)

调用noreturn(str)函数,并打印它的返回值

>>> print(noreturn("noreturn"))
noreturn
None

参数的按值传递和按引用传递

Python的函数参数既支持按值传递也支持按引用传递。

实际上,解释器会查看对象引用(内存地址)指示的那个值的类型,如果变量指示一个可变的值,就会按引用调用。如果所指示的数据的类型是不可变的,则会应用按值调用。

列表 字典 集合 类 总是会按引用传入函数,函数代码组中对变量数据结构的任何改变都会反映到调用代码中。

字符串 数值 元组 总是会按值传入函数,函数中对变量的任何修改是这个函数私有的,不会反映到调用代码中。

>>> def demo(num, list):
...     num = num + 1
...     list.append(3)
...
>>> num=1
>>> list=[1, 2]
>>> demo(num, list)
>>> num
1
>>> list
[1, 2, 3]

不可以

默认参数

上例中定义的参数,在调用函数时必须传递给函数。 如果函数定义了多个参数,调用时必须还按正确位置顺序传递。这意味着,调用时的参数数量应该与函数定义时的数量相等。

定义参数时,可以给参数指定一个默认值,这样的参数叫做默认参数,它允许调用时选择传递或不传递此参数,如下例所示。

def checkAge(age, minAge=18):
    "检查年龄,小于minAge返回False"
    if(age < minAge):
        return False
    else:
        return True

调用此函数:

>>> checkAge(15)
False
>>> checkAge(15,14)
True

重要提示:默认值的定义仅执行一次。 当默认值是可变对象(例如列表、字典或大多数类的实例)时,它导致函数执行结果不同。 例如,以下函数在后续调用中累积传递给它的参数:

def f(a, L=[]):
    L.append(a)
    return L

print(f(1))
print(f(2))
print(f(3))

执行如下代码:

[1]
[1, 2]
[1, 2, 3]

如果您不希望在后续调用之间共享默认值,则可以这样编写函数:

def f(a, L=None):
    if L is None:
        L = []
    L.append(a)
    return L

位置参数关键字参数

在前面的例子中,调用函数时的每个参数都是和定义参数时的参数一一对应的。它们的位置决定了传递的是那个参数,这样的参数叫做位置参数。

关键字参数与函数调用相关。 在函数调用中使用关键字参数时,调用者通过参数名称指定传递的是那个参数。

这允许您跳过参数表中的某些参数或将它们的顺序打乱放置,因为Python解释器能够使用关键字将值与参数匹配。 您可以通过以下方式对checkAge()函数进行关键字调用:

下面的调用方式是允许的:

checkAge(15)                        # 1个位置参数
checkAge(age = 15)                  # 1个关键字参数
checkAge(age = 15, minAge = 14)     # 2个关键字参数
checkAge(15, 14)                    # 2个位置参数
checkAge(15, minAge = 14)           # 1个位置参数,1个关键字参数

下面的调用方式是不允许的

checkAge()                  # 缺少必须参数
checkAge(age = 15, 14)      # 非关键字参数在关键字参数之后
checkAge(15, age = 14)      # 重复相同的参数
checkAge(actor = 14)        # 未知参数

在函数调用中,关键字参数必须跟在位置参数之后。 传递的所有关键字参数必须与函数接受的参数之一匹配(例如actor不是checkAge函数的有效参数),并且它们的顺序并不重要。