当前位置: 首页 > 后端技术 > Python

再见!Python那些不为人知的大坑

时间:2023-03-26 19:35:33 Python

“Python很简单”似乎已经成为了很多开发者的共识。确实,它的表达方式非常接近自然语言。不需要像C++那样去思考指针和内存,也不需要像Java那样去深入理解JVM。慢慢地,开发人员开始认为“我们写的代码是完全正确的”。但是在忽略Python细节的过程中,你会发现会出现奇怪的错误。回过头来定位问题的时候,找了半天也没能定位到问题,在网上搜索也没有找到对应的解决方法。回头看代码,感觉代码无懈可击。殊不知,在开发过程中出现了很多错误。在本文中,我将总结Python初学者经常遇到的5个错误。说实话,我犯的一些错误是陷阱,很长一段时间都逃不掉。希望把这些问题总结一下,防止大家再次踩坑!1.字典复制在某些场景下,需要复制字典的副本。这个副本用于保存原始数据,然后原始字典用于其他操作,或者作为参数传递给一些函数。例如,>>>dict_a={"name":"John","address":"221BBakerstreet"}>>>dict_b=dict_a使用赋值算法将dict_a赋值给dict_b后,这些值两个变量相同。你可以带着dict_b参与其他操作,例如更新/添加键值对。但事实并不是你想的那样。如果你更新或编辑dict_b,dict_a也会相应地改变。有关详细信息,您可以了解Python可变对象和不可变对象。我们来看看效果:>>>dict_b["age"]=26>>>dict_b{'address':'221BBakerstreet','name':'John','age':26}>>>dict_a{'address':'221BBakerstreet','name':'John','age':26}你会发现dict_b增加了一个age:26的键值对,dict_a也更新了。这样,我们留下一个副本就没有意义了。解决这个问题可以使用Python中的浅拷贝copy和深拷贝deepcopy来解决。我们来看一下,>>>dict_c=dict_b.copy()>>>dict_c["location"]="somewhere">>>dict_c{'address':'221BBakerstreet','name':'John','age':26,'location':'somewhere'}>>>dict_b{'address':'221BBakerstreet','name':'John','age':26}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不见了!这是因为,在Python中,True相当于1,False相当于0。因此,在代码dict_a[True]="mango"这行中,将原来的键值替换为1。您可以验证True是否等于1:>>>isinstance(True,int)True>>>True==1True3。更新列表或字典也是一样,先看一个列表的例子:>>>list_a=[1,2,3,4,5]>>>list_a=list_a.append(6)>>>list_a#不要输出任何东西,看一个字典的例子:>>>dict_a={"a":"b"}>>>dict_a=dict_a.update({"c":"d"})>>>dict_a#不输出任何内容发现打印list_a和dict_a不输出任何内容!这是因为Python中列表和字典中的一些方法,如排序、更新、追加、添加等,不会创建不必要的副本,从而提高性能,因此不需要重新赋值给变量。看正确的方法:>>>list_a=[1,2,3,4,5]>>>list_a.append(6)>>>list_a.sort()>>>list_a[1,2,3,4,5,6]4.常驻字符串在某些情况下,Python会尝试重用现有的不可变对象。字符串驻留就是这样一种情况。我们来看一个例子对比,>>>a="gmail">>>b="gmail">>>aisbTrue并修改,>>>a="@gmail">>>b="@gmail">>>aisbFalse不是很神奇吗?我们只添加了一个@符号,结果却大不相同!在第一种实现方法中,尝试创建两个不同的字符串对象。但是当检查两个对象是否相同时,它返回True。这是因为python并没有再创建一个对象b,而是将b指向第一个值gmail,换句话说它是常驻的。但是如果字符串中有除ASCII字符、数字、下划线以外的字符,它就不会留下来,所以它不会再指向@gmail了。这里要注意is和==的操作是不一样的。==用于判断值是否相等,不仅需要值相等,还需要指向同一个对象。>>>a="@gmail">>>b="@gmail">>>a是bFalse>>>a==bTrue5。默认参数只计算一次。让我们看一下下面的例子:>>>deffunc(a,lst=[]):...lst。append(a)...returnlst...>>>print(func(1))[1]>>>print(func(2))[1,2]这里发生了什么?我在func中给了一个默认参数[],然后先后调用了2次func函数。按照我们常规的理解,这两个调用是分开的。第一次调用输出[1],第二次调用输出[2]。为什么第一次调用的列表仍然保留在第二次调用中?价值?这是因为在Python中,默认参数只被评估一次。第一次调用func(1)时,它使用默认参数。但是,第二次调用将不再计算默认参数,直接在[1]的基础上追加一个值。结论您可能没有遇到本文介绍的这些常见错误,因此您可能会感到不以为然。但是,这5个问题所涵盖的功能,在开发一个小模块的时候,总会在某个时间点不知不觉中用到其中一个功能。如果想当然地按照自己的观念去做,结果可想而知,就会出现错误。因此,在Python开发的过程中,要注意一些细节问题,深入系统地学习Python,避免在Python的一些基本特性上犯错误。如果你对Python有扎实的了解,你自然会避免这些错误。反而会给自己带来很大的麻烦,一旦出错就很难定位。以上就是本次分享的全部内容。觉得文章还不错的话,请关注公众号:Python编程学习圈,每日干货分享,发送“J”还能收到海量学习资料,涵盖Python电子书和教程,数据库编程、Django、爬虫、云计算等。或者去编程学习网了解更多编程技术知识。