首页 > 编程 > Python > 正文

浅谈使用Python变量时要避免的3个错误

2020-02-16 10:31:58
字体:
来源:转载
供稿:网友

Python编程中经常遇到一些莫名其妙的错误, 其实这不是语言本身的问题, 而是我们忽略了语言本身的一些特性导致的,今天就来看下使用Python变量时导致的3个不可思议的错误, 以后在编程中要多多注意。

关于Python编程运行时新手易犯错误,这里暂不作介绍,详情参见:Python运行的17个时新手常见错误小结

1、 可变数据类型作为函数定义中的默认参数

这似乎是对的?你写了一个小函数,比如,搜索当前页面上的链接,并可选将其附加到另一个提供的列表中。

def search_for_links(page, add_to=[]):  new_links = page.search_for_links()  add_to.extend(new_links)  return add_to

从表面看,这像是十分正常的 Python 代码,事实上它也是,而且是可以运行的。但是,这里有个问题。如果我们给 add_to 参数提供了一个列表,它将按照我们预期的那样工作。但是,如果我们让它使用默认值,就会出现一些神奇的事情。

试试下面的代码:

def fn(var1, var2=[]):  var2.append(var1)  print(var2)fn(3)fn(4)fn(5)

可能你认为我们将看到:

[3][4][5]

但实际上,我们看到的却是:

[3][3,4][3,4,5]

为什么呢?如你所见,每次都使用的是同一个列表,输出为什么会是这样?在 Python 中,当我们编写这样的函数时,这个列表被实例化为函数定义的一部分。当函数运行时,它并不是每次都被实例化。这意味着,这个函数会一直使用完全一样的列表对象,除非我们提供一个新的对象:

fn(3,[4])[4,3]

答案正如我们所想的那样。要想得到这种结果,正确的方法是:

def fn(var1, var2=None):  ifnot var2:    var2 =[]  var2.append(var1)

或是在第一个例子中:

def search_for_links(page, add_to=None):  ifnot add_to:    add_to =[]  new_links = page.search_for_links()  add_to.extend(new_links)  return add_to

这将在模块加载的时候移走实例化的内容,以便每次运行函数时都会发生列表实例化。请注意,对于不可变数据类型,比如元组、字符串、整型,是不需要考虑这种情况的。这意味着,像下面这样的代码是非常可行的:

def func(message="my message"):  print(message)

2、 可变数据类型作为类变量

这和上面提到的最后一个错误很相像。思考以下代码:

class URLCatcher(object):  urls =[]  def add_url(self, url):    self.urls.append(url)

这段代码看起来非常正常。我们有一个储存 URL 的对象。当我们调用 add_url 方法时,它会添加一个给定的 URL 到存储中。看起来非常正确吧?让我们看看实际是怎样的:

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表