关于python:如何使用pass语句?

How to use the pass statement?

我正在学习python,我已经到达了关于pass语句的部分。我使用的指南将其定义为一个通常用作占位符的Null语句。

但我还是不完全理解这意味着什么。有人能告诉我一个简单的/基本的情况,在那里使用pass语句,以及为什么需要它?


假设您正在用一些您还不想实现的方法设计一个新类。

1
2
3
4
5
6
class MyClass(object):
    def meth_a(self):
        pass

    def meth_b(self):
        print"I'm meth_b"

如果不考虑pass,代码就不会运行。

然后你会得到一个:

1
IndentationError: expected an indented block

总而言之,pass语句没有什么特别之处,但它可以充当占位符,如本文所示。


python的语法要求代码块(在if之后、except之后、def之后、class之后)不能为空。但是,空代码块在各种不同的上下文中都很有用,例如在下面的示例中,这是我见过的最常见的用例。

因此,如果代码块中不应该发生任何事情,那么需要一个pass,这样的块才能不生成IndentationError。或者,可以使用任何语句(包括只评估一个术语,如Ellipsis文字...或字符串,通常是docstring),但pass明确表示实际上不应该发生任何事情,不需要实际评估和(至少暂时)存储在内存中。

  • 忽略(全部或)某种类型的Exception(来自xml的例子):

    1
    2
    3
    4
    try:
        self.version ="Expat %d.%d.%d" % expat.version_info
    except AttributeError:
        pass # unknown

    注意:忽略所有类型的加薪,如下面来自pandas的示例,通常被认为是不好的做法,因为它还捕获了可能传递给调用者的异常,例如KeyboardInterruptSystemExit甚至HardwareIsOnFireError,您如何知道您没有在自定义框中运行特定的错误定义哪个调用应用程序想知道?).

    1
    2
    3
    4
    try:
        os.unlink(filename_larry)
    except:
        pass

    相反,至少使用except Error:或在这种情况下,最好使用except OSError:被认为是更好的做法。对我安装的所有python模块进行了快速分析,发现超过10%的except ...: pass语句捕获了所有异常,因此它仍然是python编程中的常见模式。

  • 派生不添加新行为的异常类(例如在scipy中):

    1
    2
    class CompileError(Exception):
        pass

    类似地,打算作为抽象基类的类通常具有显式空的__init__或子类应该派生的其他方法。(如pebl)

    1
    2
    3
    class _BaseSubmittingController(_BaseController):
        def submit(self, tasks): pass
        def retrieve(self, deferred_results): pass
  • 在不考虑结果的情况下(来自mpmath)对一些测试值进行代码正常运行的测试:

    1
    2
    3
    for x, error in MDNewton(mp, f, (1,-2), verbose=0,
                             norm=lambda x: norm(x, inf)):
        pass
  • 在类或函数定义中,通常docstring已经作为必选语句就位,作为块中唯一要执行的语句。在这种情况下,该块除了包含docstring外,还可以包含pass,以便说"这确实是为了什么都不做。"例如,在pebl中:

    1
    2
    3
    class ParsingError(Exception):
       """Error encountered while parsing an ill-formed datafile."""
        pass
  • 在某些情况下,pass用作占位符,表示"this method/class/if block/"。虽然我个人更喜欢使用Ellipsis字面的...,以便严格区分这一点和前一个例子中的故意"禁止操作",但还没有实现,但这将是实现这一点的地方。例如,如果我用大笔画出一个模型,我可能会写

    1
    2
    def update_agent(agent):
        ...

    其他人可能有的地方

    1
    2
    def update_agent(agent):
        pass

    之前

    1
    2
    3
    def time_step(agents):
        for agent in agents:
            update_agent(agent)

    提醒您稍后填写update_agent函数,但已经运行了一些测试,以查看其余代码是否按预期运行。(第三种选择是raise NotImplementedError。这在两种情况下特别有用:要么"这个抽象方法应该由每个子类实现,在这个基类中没有通用的方法来定义它",要么"这个具有这个名称的函数还没有在这个版本中实现,但是它的签名看起来是这样的")。


除了用作未实现函数的占位符之外,pass还可以用于填写if-else语句("explicit优于implicit")。

1
2
3
4
5
6
7
8
9
10
11
12
def some_silly_transform(n):
    # Even numbers should be divided by 2
    if n % 2 == 0:
        n /= 2
        flag = True
    # Negative odd numbers should return their absolute value
    elif n < 0:
        n = -n
        flag = True
    # Otherwise, number should remain unchanged
    else:
        pass

当然,在这种情况下,可能会使用return而不是赋值,但在需要突变的情况下,这是最好的方法。

这里使用EDOCX1[0]特别有用,可以警告未来的维护人员(包括您自己!)不要把多余的步骤放在条件语句之外。在上面的例子中,flag是在两个特别提到的案例中设置的,而不是在else案例中设置的。如果不使用pass,未来的程序员可能会将flag = True移动到条件之外,从而在所有情况下设置flag

另一种情况是文件底部经常出现的样板函数:

1
2
if __name__ =="__main__":
    pass

在某些文件中,最好将其保留在pass中,以便以后更容易编辑,并明确指出当文件单独运行时,预计不会发生任何事情。

最后,如其他答案中所述,在捕获异常时不执行任何操作可能很有用:

1
2
3
4
try:
    n[i] = 0
except IndexError:
    pass


认为pass的最好和最准确的方法是明确地告诉解释器什么都不做。以同样的方式,以下代码:

1
2
def foo(x,y):
    return x+y

意思是"如果我调用函数foo(x,y),将标签x和y表示的两个数字相加,并返回结果",

1
2
def bar():
    pass

意思是"如果我调用函数bar(),什么也不做。"

其他的答案是非常正确的,但对于一些不涉及保留位置的事情也很有用。

例如,在我最近编写的一段代码中,有必要将两个变量分开,除数可能为零。

1
c = a / b

显然,如果b为零,会产生一个零分割误差。在这种特殊情况下,在B为零的情况下,将C保留为零是所需的行为,因此我使用了以下代码:

1
2
3
4
try:
    c = a / b
except ZeroDivisionError:
    pass

另一个不太标准的用法是作为放置调试器断点的方便位置。例如,我希望有一点代码能够在for的第20次迭代中闯入调试器。在陈述中。所以:

1
2
3
4
for t in range(25):
    do_a_thing(t)
    if t == 20:
        pass

通过断点。


一个可以"原样"使用的常见用例是重写一个类来创建一个类型(否则它与超类相同),例如。

1
2
class Error(Exception):
    pass

因此,您可以引发并捕获Error异常。这里重要的是异常的类型,而不是内容。


如果你不知道你要把什么放在一个特定的代码块中

1
2
3
4
try:
   int(someuserinput)
except ValueError:
   pass

我也喜欢在考试中使用它。我经常意识到我想测试什么,但不太知道该怎么做。测试示例看起来像塞巴斯蒂安·奥伊建议的那样

1
2
3
4
5
6
7
class TestFunctions(unittest.TestCase):

   def test_some_feature(self):
      pass

   def test_some_other_feature(self):
      pass


python中的pass基本上什么都不做,但与注释不同的是,它不会被解释器忽略。因此,你可以在很多地方利用它,让它成为一个地方持有者:

1:可在课堂上使用

1
2
   class TestClass:
      pass

2:可以在循环和条件语句中使用:

1
2
3
4
5
   if (something == true):  # used in conditional statement
       pass

   while (some condition is true):  # user is not sure about the body of the loop
       pass

3:可用于功能:

1
2
   def testFunction(args): # programmer wants to implement the body of the function later
       pass

pass主要用于程序员目前不想给出实现,但仍想创建一个特定的类/函数/条件语句,以后可以使用。由于python解释器不允许空白或未实现的类/函数/条件语句,因此它给出了一个错误:

IndentationError: expected an indented block

pass可用于此类情况。


你可以说,通过意味着没有操作。在这个例子之后,您将得到一个清晰的画面:

C程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include<stdio.h>

void main()
{
    int age = 12;

    if( age < 18 )
    {
         printf("You are not adult, so you can't do that task");
    }
    else if( age >= 18 && age < 60)
    {
        // I will add more code later inside it
    }
    else
    {
         printf("You are too old to do anything , sorry");
    }
}

现在,您将如何用python编写它:

1
2
3
4
5
6
7
8
9
10
11
age = 12

if age < 18:

    print"You are not adult, so you can't do that task"

elif age >= 18 and age < 60:

else:

    print"You are too old to do anything , sorry"

但是您的代码会出错,因为它需要ELIF后面的缩进块。下面是pass关键字的角色。

1
2
3
4
5
6
7
8
9
10
11
12
13
age = 12

if age < 18:

    print"You are not adult, so you can't do that task"

elif age >= 18 and age < 60:

    pass

else:

    print"You are too old to do anything , sorry"

现在我想你明白了。


老实说,我认为官方的python文档很好地描述了它,并提供了一些示例:

The pass statement does nothing. It can be used when a statement is required syntactically but the program requires no action. For example:

>>> while True:
... pass # Busy-wait for keyboard interrupt (Ctrl+C)
...

This is commonly used for creating minimal classes:

>>> class MyEmptyClass:
... pass
...

Another place pass can be used is as a place-holder for a function or conditional body when you are working on new code, allowing you to keep thinking at a more abstract level. The pass is silently ignored:

>>> def initlog(*args):
... pass # Remember to implement this!
...


pass语句不起作用。它可以在句法上需要语句但程序不需要操作时使用。


正如书中所说,我只是把它当作一个临时的占位符。

1
2
3
4
5
# code that does something to to a variable, var
if var == 2000:
    pass
else:
    var += 1

然后再填写一个场景,其中var == 2000


pass指的是ignore….尽管很简单….如果给定的条件为true,而下一条语句为pass,则忽略该值或迭代,并继续下一行…..例子

1
2
3
4
5
For i in range (1,100):
    If i%2==0:
                  Pass
    Else:
                  Print(i)

输出:打印1-100之间的所有奇数

这是因为偶数的模等于零,因此它忽略该数并继续到下一个数,因为奇数模不等于零,所以执行循环的其他部分并打印它


当语法上需要语句,但不希望执行任何命令或代码时,可以使用python中的pass语句。

pass语句是一个空操作;执行时不会发生任何事情。在代码最终会消失但尚未写入的地方(例如,在存根中),pass也很有用:

例如:

1
2
3
4
5
6
7
8
9
#!/usr/bin/python

for letter in 'Python':
   if letter == 'h':
      pass
      print 'This is pass block'
   print 'Current Letter :', letter

print"Good bye!"

这将产生以下结果:

1
2
3
4
5
6
7
8
Current Letter : P
Current Letter : y
Current Letter : t
This is pass block
Current Letter : h
Current Letter : o
Current Letter : n
Good bye!

如果字母的值为"h",则前面的代码不执行任何语句或代码。当您创建了一个代码块但不再需要它时,pass语句很有用。

然后您可以删除块内的语句,但让块保留在pass语句中,这样它就不会干扰代码的其他部分。


这里有一个例子,我从一个列表中提取特定的数据,在这个列表中我有多个数据类型(这就是我在R中称之为的——抱歉,如果命名错误的话),我只想提取整数/数字而不是字符数据。

数据如下:

1
2
3
4
5
6
7
8
>>> a = ['1', 'env', '2', 'gag', '1.234', 'nef']
>>> data = []
>>> type(a)
<class 'list'>
>>> type(a[1])
<class 'str'>
>>> type(a[0])
<class 'str'>

我想删除所有字母字符,所以我让机器通过子集数据和"传递"字母数据来完成:

1
2
3
4
5
6
7
8
9
a = ['1', 'env', '2', 'gag', '1.234', 'nef']
data = []
for i in range(0, len(a)):
    if a[i].isalpha():
        pass
    else:
        data.append(a[i])
print(data)
['1', '2', '1.234']