page contents

你在使用Python时犯过这3个错误吗?

常见错误1:错误地将表达式作为函数的默认参数 在Python中,我们可以为函数的某个参数设置默认值,使该参数成为可选参数。虽然这是一个很好的语言特性,但是当默认值是可变类型时,也会导致一...

常见错误1:错误地将表达式作为函数的默认参数

在Python中,我们可以为函数的某个参数设置默认值,使该参数成为可选参数。虽然这是一个很好的语言特性,但是当默认值是可变类型时,也会导致一些令人困惑的情况。我们来看看下面这个Python函数定义:

>>> def foo(bar=[]): # bar是可选参数,如果没有提供bar的值,则默认为[],... bar.append("baz") # 但是稍后我们会看到这行代码会出现问题。... return bar

Python程序员常犯的一个错误,就是想当然地认为:在每次调用函数时,如果没有为可选参数传入值,那么这个可选参数就会被设置为指定的默认值。在上面的代码中,你们可能觉得重复调用foo()函数应该会一直返回’baz’,因为你们默认每次foo()函数执行时(没有指定bar变量的值),bar变量都被设置为[](也就是,一个新的空列表)。但是,实际运行结果却是这样的:

>>> foo()["baz"]>>> foo()["baz", "baz"]>>> foo()["baz", "baz", "baz"]

很奇怪吧?为什么每次调用foo()函数时,都会把”baz”这个默认值添加到已有的列表中,而不是重新创建一个新的空列表呢?答案就是,可选参数默认值的设置在Python中只会被执行一次,也就是定义该函数的时候。因此,只有当foo()函数被定义时,bar参数才会被初始化为默认值(也就是,一个空列表),但是之后每次foo()函数被调用时,都会继续使用bar参数原先初始化生成的那个列表。当然,一个常见的解决办法就是:

>>> def foo(bar=None):... if bar is None: # or if not bar:... bar = []... bar.append("baz")... return bar...>>> foo()["baz"]>>> foo()["baz"]>>> foo()["baz"]


常见问题2:错误地使用类变量

我们来看下面这个例子:

>>> class A(object):... x = 1...>>> class B(A):... pass...>>> class C(A):... pass...>>> print A.x, B.x, C.x1 1 1

这个结果很正常。

>>> B.x = 2>>> print A.x, B.x, C.x1 2 1

嗯,结果和预计的一样。

>>> A.x = 3>>> print A.x, B.x, C.x3 2 3

在Python语言中,类变量是以字典的形式进行处理的,并且遵循方法解析顺序(Method Resolution Order,MRO)。因此,在上面的代码中,由于类C中并没有x这个属性,解释器将会查找它的基类(base class,尽管Python支持多重继承,但是在这个例子中,C的基类只有A)。换句话说,C并不没有独立于A、真正属于自己的x属性。所以,引用C.x实际上就是引用了A.x。如果没有处理好这里的关系,就会导致示例中出现的这个问题。


常见错误3:错误地指定异常代码块(exception block)的参数

请看下面这段代码:

>>> try:... l = ["a", "b"]... int(l[2])... except ValueError, IndexError: # To catch both exceptions, right?... pass...Traceback (most recent call last):File "", line 3, inIndexError: list index out of range

这段代码的问题在于,except语句并不支持以这种方式指定异常。在Python 2.x中,需要使用变量e将异常绑定至可选的第二个参数中,才能进一步查看异常的情况。因此,在上述代码中,except语句并没有捕获IndexError异常;而是将出现的异常绑定到了一个名为IndexError的参数中。要想在except语句中正确地捕获多个异常,则应将第一个参数指定为元组,然后在元组中写下希望捕获的异常类型。另外,为了提高可移植性,请使用as关键词,Python 2和Python 3均支持这种用法。

>>> try:... l = ["a", "b"]... int(l[2])... except (ValueError, IndexError) as e:... pass...>>>

  • 发表于 2020-03-03 09:55
  • 阅读 ( 599 )
  • 分类:Python开发

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
Pack
Pack

1135 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 1316 文章
  3. Pack 1135 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章