发布于 2026-01-05 12 阅读
0

Python 初学者常犯的 5 个错误

Python 初学者常犯的 5 个错误

原文发表于pythoncircle.com

在 Python 编程的初期,我们每个人都会遇到各种各样的奇怪 bug,在 Stack Overflow 上花费数小时苦苦寻找答案后,最终发现这并非 bug,而是 Python 的特性。这就是 Python 的运作方式。以下列出了 Python 初学者最常犯的 5 个错误。让我们来了解一下这些错误,这样就能省去在 Facebook 页面和群组里提问的几个小时。

- 创建字典或列表的副本。

当你需要复制字典或列表时,不要直接使用赋值运算符。

错误的:

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

现在,如果您编辑/更新dict_bdict_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()ordeepcopy()方法。

>>> 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}
>>> 

了解复制和深度复制之间的区别。

- 字典键。

假设我们将以下值放入一个字典中。

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

如果我们尝试打印这个字典,输出结果会是什么?让我们看看。

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

刚才发生了什么?键在哪里True
记住,布尔类是整数类的子类。整数中True1 的等价值为 1,2 的等价值False为 0。因此,键 1 的值被覆盖了。

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

- 更新列表或字典。
假设你想向列表中添加一个项目。

>>> 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

为什么什么都没打印出来?我们做错了什么?

序列对象的大部分方法,如排序、更新、追加、添加等,都采用原地操作,避免不必要地创建单独的副本,从而提高性能。

不要尝试将此类方法的输出赋值给变量。

正道:

>>> 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]

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

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

这里我们尝试创建两个不同的字符串对象。但是,当检查这两个对象是否相同时,返回了 True。这是因为 Python 没有创建新对象,b而是指向了b第一个值“gmail”。

长度为 1 的所有字符串都会被内部存储。除了 ASCII 字符、数字和下划线之外的任何字符都不会被内部存储。

让我们来看看。

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

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

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

==因此,在使用不可变字符串或运算符时,请记住上述要点is

- 默认参数只计算一次。

请看下面的例子。

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]。

额外提示:空格和制表符不要混用。千万别混用。你会哭的。

更多内容请访问pythoncircle.com

文章来源:https://dev.to/anuragrana/5-common-mistakes-made-by-beginner-python-programmers-5ggp