”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 每个开发人员仍然面临的 ython 错误以及如何修复它们)

每个开发人员仍然面临的 ython 错误以及如何修复它们)

发布于2024-10-31
浏览:713

ython bugs that every developer is still facing in and how to fix them)

作者:Rupesh Sharma AKA @hackyrupesh

Python 以其简单性和美观性,成为世界上最流行的编程语言之一。然而,即使到了 2024 年,某些缺陷仍然困扰着开发者。这些问题并不总是由于 Python 的弱点造成的,而是由于它的设计、行为或常见的误解导致了意外的结果。在这篇博客文章中,我们将了解每个开发人员在 2024 年仍然遇到的 5 大 Python 问题及其补救措施。


1. 可变默认参数:无声陷阱

问题

最臭名昭著的 Python 错误之一是可变的默认参数。当可变对象(如列表或字典)用作函数中的默认参数时,Python 仅在定义函数时计算此默认参数一次,而不是每次调用函数时计算此默认参数。当函数修改对象时,这会导致意外的行为。

例子

def append_to_list(value, my_list=[]):
    my_list.append(value)
    return my_list

print(append_to_list(1))  # Outputs: [1]
print(append_to_list(2))  # Outputs: [1, 2] - Unexpected!
print(append_to_list(3))  # Outputs: [1, 2, 3] - Even more unexpected!

解决方案

为了避免这种情况,请使用 None 作为默认参数,并根据需要在函数内创建一个新列表。

def append_to_list(value, my_list=None):
    if my_list is None:
        my_list = []
    my_list.append(value)
    return my_list

print(append_to_list(1))  # Outputs: [1]
print(append_to_list(2))  # Outputs: [2]
print(append_to_list(3))  # Outputs: [3]

参考

  • Python 的默认参数陷阱

2. 字典中难以捉摸的KeyError

问题

当尝试访问不存在的字典键时会发生KeyError。当使用嵌套字典或处理结构无法保证的数据时,这可能特别棘手。

例子

data = {'name': 'Alice'}
print(data['age'])  # Raises KeyError: 'age'

解决方案

要防止 KeyError,请使用 get() 方法,如果找不到密钥,该方法将返回 None(或指定的默认值)。

print(data.get('age'))  # Outputs: None
print(data.get('age', 'Unknown'))  # Outputs: Unknown

对于嵌套字典,请考虑使用集合模块或 dotmap 或 pydash 等库中的 defaultdict。

from collections import defaultdict

nested_data = defaultdict(lambda: 'Unknown')
nested_data['name'] = 'Alice'
print(nested_data['age'])  # Outputs: Unknown

参考

  • Python KeyError 及其处理方法

3. 尝试例外过度使用导致的静默错误

问题

过度使用或误用 try- except 块可能会导致静默错误,即捕获异常但未正确处理异常。这可能会使错误难以检测和调试。

例子

try:
    result = 1 / 0
except:
    pass  # Silently ignores the error
print("Continuing execution...")

在上面的示例中,ZeroDivisionError 被捕获并忽略,但这可以掩盖潜在的问题。

解决方案

始终指定您要捕获的异常类型,并适当处理它。记录错误还可以帮助追踪问题。

try:
    result = 1 / 0
except ZeroDivisionError as e:
    print(f"Error: {e}")
print("Continuing execution...")

对于更广泛的异常处理,您可以使用日志记录而不是 pass:

import logging

try:
    result = 1 / 0
except Exception as e:
    logging.error(f"Unexpected error: {e}")

参考

  • Python的try- except最佳实践

4. 整数除法:截断陷阱

问题

在Python 3之前,两个整数相除默认执行向下取整除法,将结果截断为整数。尽管 Python 3 通过真正的除法 (/) 解决了这个问题,但一些开发人员在无意中使用楼层除法 (//) 时仍然面临问题。

例子

print(5 / 2)  # Outputs: 2.5 in Python 3, but would be 2 in Python 2
print(5 // 2)  # Outputs: 2

解决方案

除非您特别需要楼层划分,否则始终使用 / 进行划分。将代码从 Python 2 移植到 Python 3 时要小心。

print(5 / 2)  # Outputs: 2.5
print(5 // 2)  # Outputs: 2

为了获得清晰且可预测的代码,请考虑使用decimal.Decimal进行更准确的算术运算,尤其是在金融计算中。

from decimal import Decimal

print(Decimal('5') / Decimal('2'))  # Outputs: 2.5

参考

  • Python划分:/ vs //

5. 循环引用导致内存泄漏

问题

Python 的垃圾收集器处理大部分内存管理,但如果处理不当,循环引用可能会导致内存泄漏。当两个或多个对象相互引用时,它们可能永远不会被垃圾回收,从而导致内存使用量增加。

例子

class Node:
    def __init__(self, value):
        self.value = value
        self.next = None

node1 = Node(1)
node2 = Node(2)
node1.next = node2
node2.next = node1  # Circular reference

del node1
del node2  # Memory not freed due to circular reference

解决方案

为了避免循环引用,请考虑通过weakref模块使用弱引用,该模块允许在不存在强引用时对引用进行垃圾收集。

import weakref

class Node:
    def __init__(self, value):
        self.value = value
        self.next = None

node1 = Node(1)
node2 = Node(2)
node1.next = weakref.ref(node2)
node2.next = weakref.ref(node1)  # No circular reference now

或者,您可以在删除对象之前通过将引用设置为 None 来手动打破循环。

node1.next = None
node2.next = None
del node1
del node2  # Memory is freed

参考

  • Python内存管理和垃圾收集

结论

即使到了 2024 年,Python 开发人员仍然会遇到这些常见的错误。尽管多年来该语言不断发展和改进,但这些问题通常与 Python 工作原理的基本方面有关。通过了解这些陷阱并应用适当的解决方案,您可以编写更健壮、无错误的代码。快乐编码!


作者:Rupesh Sharma,又名 @hackyrupesh

版本声明 本文转载于:https://dev.to/hackyrupesh/5-python-bugs-that-every-developer-is-still-facing-in-2024-and-how-to-fix-them-5f4p?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 如何在Java的全屏独家模式下处理用户输入?
    如何在Java的全屏独家模式下处理用户输入?
    Handling User Input in Full Screen Exclusive Mode in JavaIntroductionWhen running a Java application in full screen exclusive mode, the usual event ha...
    编程 发布于2025-04-12
  • 如何有效地转换PHP中的时区?
    如何有效地转换PHP中的时区?
    在PHP 利用dateTime对象和functions DateTime对象及其相应的功能别名为时区转换提供方便的方法。例如: //定义用户的时区 date_default_timezone_set('欧洲/伦敦'); //创建DateTime对象 $ dateTime = ne...
    编程 发布于2025-04-12
  • 为什么我在Silverlight Linq查询中获得“无法找到查询模式的实现”错误?
    为什么我在Silverlight Linq查询中获得“无法找到查询模式的实现”错误?
    查询模式实现缺失:解决“无法找到”错误在Silverlight应用程序中,尝试使用LINQ建立LINQ连接以错误而实现的数据库”,无法找到查询模式的实现。”当省略LINQ名称空间或查询类型缺少IEnumerable 实现时,通常会发生此错误。 解决问题来验证该类型的质量是至关重要的。在此特定实例中...
    编程 发布于2025-04-12
  • 如何为PostgreSQL中的每个唯一标识符有效地检索最后一行?
    如何为PostgreSQL中的每个唯一标识符有效地检索最后一行?
    postgresql:为每个唯一标识符提取最后一行,在Postgresql中,您可能需要遇到与在数据库中的每个不同标识相关的信息中提取信息的情况。考虑以下数据:[ 1 2014-02-01 kjkj 在数据集中的每个唯一ID中检索最后一行的信息,您可以在操作员上使用Postgres的有效效率: ...
    编程 发布于2025-04-12
  • 如何将MySQL数据库添加到Visual Studio 2012中的数据源对话框中?
    如何将MySQL数据库添加到Visual Studio 2012中的数据源对话框中?
    在Visual Studio 2012 尽管已安装了MySQL Connector v.6.5.4,但无法将MySQL数据库添加到实体框架的“ DataSource对话框”中。为了解决这一问题,至关重要的是要了解MySQL连接器v.6.5.5及以后的6.6.x版本将提供MySQL的官方Visual...
    编程 发布于2025-04-12
  • ES6实战:增强对象字面量
    ES6实战:增强对象字面量
    ES6 对象字面量增强:简化 JavaScript 对象操作 ES6 引入的增强型对象字面量特性显着简化了 JavaScript 中的对象处理,主要体现在简写属性名、简写方法名和计算属性名等方面。 简写属性名使属性定义更加简洁;简写方法名简化了方法定义语法;而计算属性名则允许根据变量值动态创建属...
    编程 发布于2025-04-12
  • 揭秘mysql_real_escape_string能否防SQL注入
    揭秘mysql_real_escape_string能否防SQL注入
    MySQL_REAL_ESCAPE_STRING的限制 MySQL_REAL_ESCAPE_STRING在PHP中曾在php中曾被批评,因为他们没有为SQL注射攻击提供了不全面的攻击问题,这些问题是在潜在的攻击问题上的全面保护。尽管有些人认为该功能的用法不正确,但其他人则提出了对其固有局限性的担...
    编程 发布于2025-04-12
  • 如何从Python中的字符串中删除表情符号:固定常见错误的初学者指南?
    如何从Python中的字符串中删除表情符号:固定常见错误的初学者指南?
    从python import codecs import codecs import codecs 导入 text = codecs.decode('这狗\ u0001f602'.encode('utf-8'),'utf-8') 印刷(文字)#带有...
    编程 发布于2025-04-12
  • 如何将多种用户类型(学生,老师和管理员)重定向到Firebase应用中的各自活动?
    如何将多种用户类型(学生,老师和管理员)重定向到Firebase应用中的各自活动?
    Red: How to Redirect Multiple User Types to Respective ActivitiesUnderstanding the ProblemIn a Firebase-based voting app with three distinct user type...
    编程 发布于2025-04-12
  • 您可以使用CSS在Chrome和Firefox中染色控制台输出吗?
    您可以使用CSS在Chrome和Firefox中染色控制台输出吗?
    在javascript console 中显示颜色是可以使用chrome的控制台显示彩色文本,例如红色的redors,for for for for错误消息?回答是的,可以使用CSS将颜色添加到Chrome和Firefox中的控制台显示的消息(版本31或更高版本)中。要实现这一目标,请使用以下模...
    编程 发布于2025-04-12
  • Python高效创建XML文件:ElementTree、cElementTree还是LXML?
    Python高效创建XML文件:ElementTree、cElementTree还是LXML?
    How to Create XML Files in PythonTo create XML files in Python, consider the following options:ElementTree (Recommended)ElementTree, introduced in Pyt...
    编程 发布于2025-04-12
  • 如何在GO编译器中自定义编译优化?
    如何在GO编译器中自定义编译优化?
    在GO编译器中自定义编译优化 GO中的默认编译过程遵循特定的优化策略。 However, users may need to adjust these optimizations for specific requirements.Optimization Control in Go Compi...
    编程 发布于2025-04-12
  • 如何干净地删除匿名JavaScript事件处理程序?
    如何干净地删除匿名JavaScript事件处理程序?
    删除匿名事件侦听器将匿名事件侦听器添加到元素中会提供灵活性和简单性,但是当要删除它们时,可以构成挑战,而无需替换元素本身就可以替换一个问题。 element? element.addeventlistener(event,function(){/在这里工作/},false); 要解决此问题,请考虑...
    编程 发布于2025-04-12
  • Java是否允许多种返回类型:仔细研究通用方法?
    Java是否允许多种返回类型:仔细研究通用方法?
    在Java中的多个返回类型:一种误解类型:在Java编程中揭示,在Java编程中,Peculiar方法签名可能会出现,可能会出现,使开发人员陷入困境,使开发人员陷入困境。 getResult(string s); ,其中foo是自定义类。该方法声明似乎拥有两种返回类型:列表和E。但这确实是如此吗...
    编程 发布于2025-04-12
  • 如何在Java字符串中有效替换多个子字符串?
    如何在Java字符串中有效替换多个子字符串?
    在java 中有效地替换多个substring,需要在需要替换一个字符串中的多个substring的情况下,很容易求助于重复应用字符串的刺激力量。 However, this can be inefficient for large strings or when working with nu...
    编程 发布于2025-04-12

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3