201 lines
8.6 KiB
Markdown
201 lines
8.6 KiB
Markdown
# Python pass(什么都不做):何时以及如何使用
|
||
|
||
> 原文:[https://python.land/deep-dives/python-pass](https://python.land/deep-dives/python-pass)
|
||
|
||
Python 有一个特殊的关键字叫做`pass`。Python `pass`关键字告诉 Python 什么都不做。换句话说:只需传递这一行代码并继续。如果你习惯于用类 C 语言编程,你可能从来不需要这样的语句。
|
||
|
||
* 那么为什么这个关键字在 Python 中存在而在其他语言中不存在呢?
|
||
* 你会在哪里以及如何使用它?
|
||
|
||
本文回答了这些问题,并向您展示了需要 Python 的`pass`关键字的几种情况。我们还将看看一个有趣的替代方案,你可能会喜欢用它来代替!
|
||
|
||
目录
|
||
|
||
|
||
|
||
* [什么是 pass 关键字](#What_is_the_pass_keyword "What is the pass keyword")
|
||
* [Python 为什么需要 pass 关键字?](#Why_does_Python_need_a_pass_keyword "Why does Python need a pass keyword?")
|
||
* [何时使用 Python 的 pass 关键字](#When_to_use_Pythons_pass_keyword "When to use Python’s pass keyword")
|
||
* [何时不使用通行证](#When_not_to_use_pass "When not to use pass")
|
||
* [使用通行证的替代方案](#An_alternative_to_using_pass "An alternative to using pass")
|
||
* [Python 传球 vs 继续](#Python_pass_vs_continue "Python pass vs continue")
|
||
* [结论](#Conclusion "Conclusion")
|
||
|
||
|
||
|
||
## 什么是 pass 关键字
|
||
|
||
Python 的`pass`是关键词,就像`if`、`else`、`return`一样,其他都是关键词。`pass`什么也不做。它是一个告诉 Python 继续运行程序的关键字,忽略这一行代码。`pass`通常用作未来代码的占位符。
|
||
|
||
注意,因为`pass`本身形成了一个有效的语句,所以 pass 也可以被称为一个语句。因此,你会看到人们使用 pass 语句和 pass 关键字,这两个词都是正确的。
|
||
|
||
## Python 为什么需要 pass 关键字?
|
||
|
||
Python 依赖于缩进。Python 只能检测缩进了等量空格(通常是四个空格字符)的代码块。Python 语法是这样定义的,在某些地方需要代码。这样做是因为不在这些地方添加代码没有太大意义,并且对可读性没有帮助。
|
||
|
||
让我们来看看你*必须*有代码的四个地方。可能还有更多(请[让我知道](https://python.land/contact)),但这些是最突出的。如果您不在这些地方输入代码,Python 将退出程序,并出现一个`IndentationError`异常:
|
||
|
||
1. [功能定义](https://python.land/introduction-to-python/functions)
|
||
2. [类别定义](https://python.land/objects-and-classes)
|
||
3. [if… else 语句](https://python.land/introduction-to-python/python-boolean-and-operators)
|
||
4. [尝试…除了…最后](https://python.land/deep-dives/python-try-except)语句
|
||
|
||
为了便于演示,让我们尝试其中的一些:
|
||
|
||
```py
|
||
def myfunction():
|
||
# This function has no body, which is not allowed
|
||
|
||
myfunction()
|
||
```
|
||
|
||
Python 将无法运行此代码,并出现以下错误:
|
||
|
||
```py
|
||
File "myfile.py", line 4
|
||
myfunction()
|
||
^
|
||
IndentationError: expected an indented block after function definition on line 1
|
||
```
|
||
|
||
类似的投诉会导致其他情况:
|
||
|
||
```py
|
||
if True:
|
||
# No code, not allowed!
|
||
else:
|
||
# Here too, code is required
|
||
|
||
try:
|
||
# let's try doing nothing (not allowed)
|
||
except Exception:
|
||
# Again: this can't be empty!
|
||
|
||
class MyClass:
|
||
# A completely empty class is not allowed
|
||
```
|
||
|
||
如你所见,注释不被认为是代码,所以注释不能用来填补空白!这就是 pass 语句发挥作用的地方。在上述所有情况下,pass 语句可用于插入不执行任何操作但仍然满足某些代码就位要求的代码。让我们填补空白:
|
||
|
||
```py
|
||
def myfunction():
|
||
pass
|
||
|
||
myfunction()
|
||
|
||
if True:
|
||
pass
|
||
else:
|
||
pass
|
||
|
||
try:
|
||
pass
|
||
except Exception:
|
||
pass
|
||
|
||
class MyClass:
|
||
pass
|
||
```
|
||
|
||
这是所有有效但完全无用的代码。
|
||
|
||
## 何时使用 Python 的 pass 关键字
|
||
|
||
那么什么时候应该用`pass`?原因有几个,我觉得这几个是最常见的。
|
||
|
||
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](https://www.buymeacoffee.com/pythonland)**. It's much appreciated and allows me to keep working on this site!
|
||
|
||
### 作为占位符
|
||
|
||
如前所述,`pass`在开发过程中很有用。我们可以用它来创建存根函数和类,这些函数和类将在以后实现。这样我们可以创建不抛出错误的可运行代码,即使不是所有的函数、类、错误处理和 if-else 情况都实现了。
|
||
|
||
### 忽略异常
|
||
|
||
忽略异常是很常见的,尤其是当它们是`KeyError` s 的时候。这是一种你会经常看到的模式:
|
||
|
||
```py
|
||
try:
|
||
email = customer['email']
|
||
send_notification(email, ...)
|
||
except KeyError:
|
||
# Not the end of the world, let's continue
|
||
pass
|
||
```
|
||
|
||
我们发现了错误,但是不想做任何事情。然而,Python 需要在`except`块中的代码,所以我们使用`pass`。
|
||
|
||
### 调试时创建断点
|
||
|
||
`pass`的另一个有趣用途是在代码中创建断点。有时你想在一些代码后创建一个断点。如果代码在一个函数的末尾,你可能想在末尾添加一个额外的`pass`并在那里设置你的断点。要了解更多关于断点的知识,请务必阅读我的文章“T2”在 VSCode 中调试 Python 代码,以及“T4”关于使用 Python 调试器的文章。
|
||
|
||
### 创建没有额外功能的子类
|
||
|
||
如果您想创建一个子类而不添加功能,您可以使用`pass`来实现。如果您想创建一个自定义命名的[异常](https://python.land/deep-dives/python-try-except),这将非常方便,例如:
|
||
|
||
```py
|
||
class MyCustomException(Exception):
|
||
pass
|
||
```
|
||
|
||
## 何时不使用通行证
|
||
|
||
在我看来,在生产代码中应该非常谨慎地使用`pass`关键字。如果有,应该是偶然的。如前所述,使用`pass`忽略一个异常显然是可以的。但是你应该使用`pass`来发布充满存根的产品代码吗?我不确定!
|
||
|
||
如果您发现自己经常使用 pass 关键字,例如在`if` … `else`构造中,您可能想要尝试重写您的代码。让我们看一个例子:
|
||
|
||
```py
|
||
if customer_exists:
|
||
pass
|
||
else:
|
||
redirect_to_signup_page()
|
||
```
|
||
|
||
在上面的例子中,我们检查客户是否存在。如果是的话,我们都准备好了,我们使用`pass`继续。如果没有,我们重定向到一个注册页面。不过,像这样的代码可以很容易地重写,从而减少代码行,降低复杂性。通常,您需要做的只是颠倒逻辑:
|
||
|
||
```py
|
||
if not customer_exists:
|
||
redirect_to_signup_page()
|
||
```
|
||
|
||
我们为自己节省了两行代码,使代码更具可读性。
|
||
|
||
## 使用通行证的替代方案
|
||
|
||
我写过一篇关于 Python 中一种特殊的[对象的博客文章,这种对象叫做省略号](https://python.land/python-ellipsis)。在那篇文章中,我提到过我们可以用省略号代替`pass`。省略号对象不做任何事情,因此可以像使用`pass`一样使用它。这里有一个例子:
|
||
|
||
```py
|
||
def create_account(username, password):
|
||
# TODO: implement me
|
||
...
|
||
```
|
||
|
||
我没有使用`pass`,而是使用了构成省略号对象的三个点`...`。看起来很酷,如果你问我,它几乎乞求被一些实际的代码取代!
|
||
|
||
然而,这还不止于此。你可以把任何没有副作用的语句放在你本来应该放`pass`的地方,这里有一些可能性:
|
||
|
||
* 一个数字,比如`0`
|
||
* 一个布尔值(`True`或`False`)
|
||
* 一个字符串:“尚未实现”
|
||
|
||
尽管有这些选择,`pass`在这些情况下是事实上的标准,并且清楚地向其他人传达这是有意留空的,或者需要实现。所以当有疑问时,使用`pass`,尤其是当你在团队中工作的时候。
|
||
|
||
## Python 传球 vs 继续
|
||
|
||
很多人问我`pass`和`continue`有什么区别。他们可能看起来一样,但他们远不是一样的。而`pass`什么都不做,`continue`基本上停止当前的代码流,直接开始下一次循环迭代。因此,`continue`只能在循环内部工作,不能替代`pass`。
|
||
|
||
下面是如何在一个 [for 循环](https://python.land/introduction-to-python/python-for-loop)中使用`continue`:
|
||
|
||
```py
|
||
# Send voucher to all inactive customers
|
||
for customer in customers:
|
||
if customer.is_active():
|
||
# Skip this customer
|
||
continue
|
||
|
||
# do some stuff to send voucher
|
||
...
|
||
```
|
||
|
||
## 结论
|
||
|
||
我们学习了什么是 Python 的 pass 关键字,为什么 Python 需要`pass`关键字,以及在什么情况下应该和不应该使用它。我们甚至看到了一个非常酷的替代方案:省略号。最后,我解释了`pass`和`continue`的区别。 |