geekdoc-python-zh/docs/pythonland/12.md

12 KiB
Raw Permalink Blame History

Python 函数:代码重用的基础

原文:https://python.land/introduction-to-python/functions

函数是编程世界中一个至关重要的概念。在本文中,我们将探索 Python 函数。您将了解为什么它们如此重要,如何用 Python 的 def 关键字定义函数,如何调用函数,并且我们将了解使用函数时出现的一个主题:变量范围。

目录

Python 中的函数是什么?

让我们确切地定义一下什么是函数:

Function

A Python function is a named section of a program that performs a specific task and, optionally, returns a value

函数是任何编程语言的真正组成部分。我们用关键字def定义了一个 Python 函数。但是在我们开始这样做之前,让我们先回顾一下函数的优点,让我们看看一些您可能已经知道的内置函数。

使用功能的优势

代码重用

Python 函数可以定义一次,使用多次。因此,它有助于代码重用:您不会希望多次编写相同的代码。

函数是保持代码短小、简洁、易读的好方法。通过给函数起一个精心选择的名字,你的代码将变得更加易读,因为函数名直接解释了将会发生什么。这样,其他人(或者将来的你)就可以阅读你的代码,而且不用看全部,也能理解它在做什么,因为它有精心选择的函数名。

稍后将解释代码重用的其他形式。例如,你也可以将代码分组到模块中。

因素

函数接受一个参数,稍后您将看到它是如何工作的。这里最大的优点是,你可以通过改变参数来改变函数的行为。

返回值

函数可以返回值。该值通常是某种计算或运算的结果。事实上,一个 Python 函数甚至可以返回多个值

内置 Python 函数

在我们开始自己定义函数之前,我们先来看看 Python 的一些内置函数。先说最广为人知的内置函数,叫做print:

>>> print('Hello, readers!')
Hello, readers!
>>> print(15)
15

Print 接受一个参数并将其打印到屏幕上。

正如我们的定义中所述,函数可以选择返回值。但是,print不返回任何东西。因为它把一些东西打印到屏幕上,看起来好像是这样,但实际上不是。我们可以通过将打印语句的结果赋给一个 Python 变量来检查这一点:

>>> result = print('Hello')
Hello
>>> print(result)
None

None是 Python 中一种特殊类型的值,基本意思是“什么都不是”

另一个确实返回值的内置函数是len()。它返回你喂它的任何东西的长度:

>>> mylength = len('Hello')
>>> print(mylength)
5

创建 Python 函数

现在我们知道了如何使用函数,让我们自己创建一个简单的函数。为此,我们使用 Python 的def关键字:

>>> def say_hi():
...     print('Hi!')
...
>>> say_hi()
Hi!

虽然只有几行,但很多事情都在进行。让我们仔细分析一下:

  • 首先我们看到关键字def,这是 Python 定义一个函数的关键字。
  • 接下来是我们的函数名say_hi。
  • 然后我们遇到两个括号,(),表示这个函数不接受任何参数(不像printlen)。
  • 我们用冒号(:)结束这一行
  • 最后,我们遇到了一个使 Python 区别于许多其他编程语言的特性:缩进。

缩进

Python 使用缩进来区分属于一起的代码块。具有相同缩进的连续行是同一代码块的一部分。

为了告诉 Python 下面几行是我们函数的主体,我们需要缩进它们。你用键盘上的来缩进行。在 Python 中,使用四个空格进行缩进是一种很好的风格。整个 Python 社区都这样做。如果你点击 TAB 键Python 交互式 shell (REPL)和所有像样的编辑器将自动缩进四个空格。

Thank you for reading my tutorials. I write these in my free time, and it requires a lot of time and effort. I use ads to keep writing these free articles, I hope you understand! Support me by disabling your adblocker on my website or, alternatively, buy me some coffee. It's much appreciated and allows me to keep working on this site!

回到我们的函数:它的主体只有一行代码:print 命令。在此之后,我们再按一次 enter 键,让 Python REPL 知道这是函数的结尾。这很重要。函数后面必须有一个空行来表示函数的结束。最后,我们可以用say_hi()调用我们的函数。

Python 函数参数和自变量

我们可以通过将一个参数传递给我们的函数来使这变得更有趣。我们再次用 def 定义了一个函数,但是我们在括号之间添加了一个变量名:

>>> def say_hi(name):
...     print('Hi', name)
...
>>> say_hi('Erik')
Hi Erik

我们的函数现在接受一个值,该值被赋给变量名。我们将这样的变量称为参数,而我们提供的实际值(Erik)称为参数

Parameters and arguments

A Python function can have parameters. The values we pass through these parameters are called arguments.

如您所见,print()接受多个参数用逗号分隔。这允许我们打印“hi”和提供的姓名。为了方便起见print()会自动在两个字符串之间加一个空格。

具有多个参数的 Python 函数

让我们更进一步,定义一个有多个参数的函数:

>>> def welcome(name, location):
...     print("Hi", name, "welcome to", location)
...
>>> welcome('Erik', 'this tutorial')
Hi Erik welcome to this tutorial

没那么难;您只需在函数定义中添加更多的参数,用逗号分隔。

从函数返回

一个函数运行到该函数结束,之后 Python 返回到调用该函数的地方。在下面的示例中,我希望您在运行之前预测输出:

https://crumb.sh/embed/k2pkTYQVGMW

预测这个程序的输出

你的期望与现实相符吗?如果是这样,那么您已经很好地理解了函数调用是如何工作的。在这一点上,有些人希望看到文本“让我们问候整个世界”两次。如果你是其中之一,不要着急,继续读下去。

Python 会跟踪函数的调用点。在我们的例子中,它在第 5 行。一旦被调用Python 就会一行一行地运行函数中的代码块,直到到达函数的末尾。一旦到达函数的末尾, Python 会跳回到从调用函数的那一行:第 6 行!

简而言之:函数调用不是跳转或“转到”,而是对一段可重用代码的调用,这段代码返回到它被调用的地方。函数调用也是一个表达式:大多数函数都返回值。

返回值

到目前为止,我们的函数只打印了一些东西,没有返回任何东西。使函数更有用的是返回值的能力。让我们看一个 Python 函数如何返回值的示例:

https://crumb.sh/embed/QdrfCWZeXKu

这是从 Python 函数返回值的方式

如您所见,我们使用关键字return从函数中返回值。返回值的函数可以用在任何我们可以使用表达式的地方。在上面的例子中,我们可以将返回值赋给变量result

我们也可以在 if 语句中使用该函数。例如:

if add(1, 1) == 2:
    print("That's what you'd expect!")

空 return 语句

如果你的函数不返回任何东西,但是你仍然想从函数返回,你可以使用一个空的 return 语句。这里有一个愚蠢的例子:

def optional_greeter(name):
    if name.startswith('X'):
        # We don't greet people with weird names :p
        return

    print('Hi there, ', name)

optional_greeter('Xander')

这是一个有趣的模式;我称之为提前回归。我想早点回来,因为另一种选择是使用 if… else 语句块:

def optional_greeter(name):
    if name.startswith('X'):
        # We don't greet people with weird names :p
        pass
    else:
        print('Hi there, ', name)

optional_greeter('Xander')

你觉得哪个看起来更干净?我认为是第一种,因为它需要更少的缩进代码。虽然对于这样一个小例子来说差别很小,但是当你有更大的代码块时,这种差别就开始增加了。

变量范围

变量name只存在于我们的函数内部。我们说变量name的范围限于函数say_hi,意味着它不存在于这个函数之外。

Scope

The visibility of a variable is called scope. The scope defines which parts of your program can see and use a variable.

如果我们在所谓的程序顶层定义一个变量,那么它在任何地方都是可见的。

让我们来演示一下:

>>> def say_hi():
...    print("Hi", name)
...    answer = "Hi"
...
>>> name = 'Erik'
>>> say_hi()
Hi Erik
>>> print(answer)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'answer' is not defined

say_hi能够像预期的那样使用变量name,因为它是一个顶级变量:它随处可见。然而,在 say_hi 内部定义的answer在函数之外是未知的,并且会导致NameError。Python 给出了一个信息性的详细错误:“名称‘答案’未定义。”

默认值和命名参数

Python 的一个引人注目的特性是能够为参数提供默认值:

>>> def welcome(name='learner', location='this tutorial'):
...     print("Hi", name, "welcome to", location)
...
>>> welcome()
Hi learner welcome to this tutorial
>>> welcome(name='John')
Hi John welcome to this tutorial
>>> welcome(location='this epic tutorial')
Hi learner welcome to this epic tutorial
>>> welcome(name='John', location='this epic tutorial')
Hi John welcome to this epic tutorial

或者,如果您愿意,可以使用下面的交互式示例:

https://crumb . sh/embed/3gqc 9 ebqd 3k

默认值和命名参数的演示

因为我们的参数有一个默认值,所以您不必填写它们。如果没有,则使用默认值。如果这样做,您可以用自己的值覆盖默认值。

在显式命名参数的同时调用 Python 函数与我们迄今为止所做的不同。这些参数称为命名参数,因为我们指定了名称和值,而不仅仅是值。由于这些命名的参数,我们提供它们的顺序并不重要。仔细想想,这是让默认值变得有用的自然且唯一的方法。

如果你不想使用命名参数,你可以。当你依赖位置而不是名字时,你提供了我们所说的位置参数。位置很重要,如下所示:

>>> def welcome(name='learner', location='this tutorial'):
...     print("Hi", name, "welcome to", location)
...
>>> welcome('Erik', 'your home')
Hi Erik welcome to your home

现在,您已经学习了足够多的函数知识,可以继续学习本教程。如果你想了解更多,请阅读我的 Python 函数深潜