Python程序员新手所犯的5个常见错误2019-07-08

Python是一门相当容易入门的语言,但是不幸的是,新手通常都会犯以下5个常见错误。

在刚开始作为Python程序员的最初几天,我们所有人在代码中都会遇到一些稀奇古怪的bug,在StackOverflow网站上花费了好几个小时后,最终证明这些我们自己以为的bug其实不是bug,不过是我们不了解python特性。这只不过是Python的工作方式。下面是大多数初学者所犯的5个最常见的错误。让我们稍微了解一下,这样我们就可以节省几个小时在各种网站上和群里进行提问了。

1. 创建字典或列表的副本时碰到的错误

每当需要复制字典或列表时,不要简单地使用赋值运算符。

错误:

>>> dict_a = {"name": "John", "address":"221B Baker street"}
>>> dict_b = dict_a

现在,如果编辑/更新dict_b,dict_a也将被更新,因为通过使用赋值运算符,您试图说dict_b将指向dict_a指向的同一对象。

>>> dict_b["age"] = 26
>>> dict_b
{'address': '221B Baker street', 'name': 'John', 'age': 26}
>>> dict_a
{'address': '221B Baker street', 'name': 'John', 'age': 26}
>>> 

正确:
使用.copy()或.deepcopy()方法。

>>> dict_c = dict_b.copy()
>>> dict_c["location"] = "somewhere"
>>> dict_c
{'address': '221B Baker street', 'name': 'John', 'age': 26, 'location': 'somewhere'}
>>> dict_b
{'address': '221B Baker street', 'name': 'John', 'age': 26}
>>> dict_a
{'address': '221B Baker street', 'name': 'John', 'age': 26}
>>> 

参看copy和deepcopy的区别。

2. 输入字典的键值时碰到的错误

假设我们把下面的值放在字典里:

>>> dict_a = dict()
>>> dict_a
{}
>>> dict_a[1] = "apple"
>>> dict_a[True] = "mango"
>>> dict_a[2] = "melon"

然后我们试着打印字典,输出的是什么?让我们看看。

>>> dict_a
{1: 'mango', 2: 'melon'}

刚刚发生了什么?True键哪儿去了?

要记住布尔类也是整数类的子类。等于True的整数等于1,等于False的整数等于0。因此,键1的值被覆盖。
检验一下:

>>> isinstance(True, int)
True
>>> isinstance(False, int)
True
>>> True == 1
True
>>> False == 0
True
>>> 

3. 更新列表或字典时碰到的错误

假设您想要给某个列表附加一个项:

>>> list_a = [1, 2, 3, 4, 5]
>>> list_a = list_a.append(6)
>>> list_a
>>> # prints nothing

再试着更新某个字典:

>>> dict_a = {"a" : "b"}
>>> dict_a = dict_a.update({"c" : "d"})
>>> dict_a
>>> # prints nothing

好吧,再让我们试着对某个列表进行排序吧:

>>> list_b = [2,5,3,1,7]
>>> list_b = list_b.sort()
>>> list_b
>>> # prints nothing

为什么一直都打印不出任何东西来?我们正在做错了什么吗?

大多数序列对象的各种方法,比如sort、update、append、add、等等,它们的工作方式都是要想方设法避免产生不必要的多余的副本。

不要尝试把这些方法的输出内容赋值给各种变量。

正确的方法:

>>> list_a = [1, 2, 3, 4, 5]
>>> list_a.append(6)
>>> dict_a = {"a" : "b"}
>>> dict_a.update({"c" : "d"})
>>> dict_a
{'c': 'd', 'a': 'b'}
>>> list_a.sort()
>>> list_a
[1, 2, 3, 4, 5, 6]

4. 驻留字符串(Interned Strings)

在某些情况下,Python尝试重用现有的不可变对象。字符串驻留就是这样一种情况。

>>> a = "gmail"
>>> b = "gmail"
>>> a is b
True

这里我们尝试创建两个不同的字符串对象。但当检查两个对象是否相同时,它返回true。这是因为python没有创建另一个对象b,而是将b指向第一个值“gmail”。
长度为1的所有字符串都是驻留字符串。一个除了任何ASCII字符、数字和下划线之外的任何内容的字符串都不是驻留字符串。
让我们看一下:

>>> a = "@gmail"
>>> b = "@gmail"
>>> a is b
False
>>> 

另外,记住==与is运算符不同。==检查值是否相等,而is检查两个变量是否都指向同一对象。

让我们看以下。

>>> a = "@gmail"
>>> b = "@gmail"
>>> a is b
False
>>> a == b
True
>>> 

因此,在使用不可变的字符串或==或isoperator时,请记住上述要点。

5. 默认参数只计算一次的错误

让我们考虑一下下面的例子:

def func(a, lst=[]):
    lst.append(a)
    return lst

print(func(1))
print(func(2))

你认为上面的两条打印语句将会输出什么内容?
让我们试着运行一下:

>>> def func(a, lst=[]):
...     lst.append(a)
...     return lst
... 
>>> print(func(1))
[1]
>>> print(func(2))
[1, 2]
>>> 

为什么第二个例子的输出是[1, 2]?难道不应该只是[2]吗?

这里的要点是,函数的默认参数只计算一次。在第一次调用(即func(1))时,计算列表lst,并发现它是空列表,因此将1附加到它的最后位置。但是在第二个调用中,列表已经有一个元素,因此输出是[1,2]

你可能感兴趣的:(Python程序员新手所犯的5个常见错误2019-07-08)