Python 常见问题梳理

一、基础语法问题

1. 缩进错误

python 复制代码
# 错误示例
if True:
print("Hello")  # IndentationError

# 正确示例
if True:
    print("Hello")

2. 变量作用域混淆

python 复制代码
x = 10
def func():
    x = 20  # 这是局部变量
    print(x)  # 20

func()
print(x)  # 10

# 使用 global 关键字
def func2():
    global x
    x = 30
    print(x)  # 30

3. 可变默认参数陷阱

python 复制代码
# 错误示例
def func(items=[]):
    items.append(1)
    return items

print(func())  # [1]
print(func())  # [1, 1]  ❌

# 正确示例
def func(items=None):
    if items is None:
        items = []
    items.append(1)
    return items

二、数据结构常见问题

1. 列表浅拷贝 vs 深拷贝

python 复制代码
import copy

# 浅拷贝
list1 = [[1,2], [3,4]]
list2 = list1.copy()  # 或 list2 = list1[:]
list1[0][0] = 99
print(list2)  # [[99, 2], [3, 4]]  ❌

# 深拷贝
list3 = copy.deepcopy(list1)
list1[0][0] = 100
print(list3)  # [[99, 2], [3, 4]]  ✅

2. 字典键必须是不可变类型

python 复制代码
# 错误示例
# d = {[1,2]: "value"}  # TypeError

# 正确示例
d = {
    (1,2): "value",  # 元组可以作为键
    "key": "value",
    123: "value"
}

3. 集合去重原理

python 复制代码
# 基于 __hash__ 和 __eq__ 方法
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    def __hash__(self):
        return hash((self.name, self.age))
    
    def __eq__(self, other):
        return self.name == other.name and self.age == other.age

p1 = Person("Alice", 25)
p2 = Person("Alice", 25)
print(len({p1, p2}))  # 1

三、函数与方法

1. 参数传递方式

python 复制代码
# 不可变对象:传值
def modify_num(x):
    x = 100

num = 10
modify_num(num)
print(num)  # 10

# 可变对象:传引用
def modify_list(lst):
    lst.append(4)

my_list = [1,2,3]
modify_list(my_list)
print(my_list)  # [1, 2, 3, 4]

2. lambda 函数限制

python 复制代码
# lambda 只能包含单个表达式
# 错误:lambda x: if x>0: return x else: return -x
# 正确:
abs_val = lambda x: x if x > 0 else -x

# 复杂的逻辑应该使用普通函数

3. 闭包变量绑定

python 复制代码
# 常见问题
functions = []
for i in range(3):
    functions.append(lambda: print(i))

for f in functions:
    f()  # 全部输出 2 ❌

# 解决方案
functions = []
for i in range(3):
    functions.append(lambda x=i: print(x))

for f in functions:
    f()  # 0, 1, 2 ✅

四、面向对象编程

1. 类变量与实例变量

python 复制代码
class MyClass:
    class_var = 0  # 类变量
    
    def __init__(self, value):
        self.instance_var = value  # 实例变量

obj1 = MyClass(1)
obj2 = MyClass(2)

obj1.class_var = 99  # 创建实例属性,不会修改类变量
MyClass.class_var = 100  # 修改类变量

2. 继承与 super()

python 复制代码
class Parent:
    def __init__(self):
        print("Parent init")

class Child(Parent):
    def __init__(self):
        super().__init__()  # Python 3 语法
        print("Child init")

3. 特殊方法 str vs repr

python 复制代码
class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    
    def __str__(self):
        return f"Point({self.x}, {self.y})"
    
    def __repr__(self):
        return f"Point(x={self.x}, y={self.y})"

p = Point(1, 2)
print(str(p))   # Point(1, 2)
print(repr(p))  # Point(x=1, y=2)

五、异常处理

1. 正确捕获多个异常

python 复制代码
try:
    # 可能出错的代码
    result = 10 / 0
except (ZeroDivisionError, ValueError) as e:
    print(f"Error: {e}")
except Exception as e:
    print(f"Unexpected error: {e}")
finally:
    print("Cleanup")

2. 避免空的 except 语句

python 复制代码
# 错误示例
try:
    do_something()
except:
    pass  # 会捕获所有异常,包括 KeyboardInterrupt

# 正确示例
try:
    do_something()
except Exception as e:  # 不会捕获 KeyboardInterrupt, SystemExit
    log_error(e)

六、模块与包

1. 循环导入问题

python 复制代码
# module_a.py
import module_b  # ❌ 循环导入

def func_a():
    from module_b import func_b  # ✅ 延迟导入
    return func_b()

2. name == "main"

python 复制代码
# 模块可以自己运行,也可以被导入
def main():
    print("This is the main function")

if __name__ == "__main__":
    main()  # 直接运行脚本时执行

七、性能与内存

1. 字符串拼接优化

python 复制代码
# 低效
result = ""
for i in range(10000):
    result += str(i)

# 高效
result = "".join(str(i) for i in range(10000))

2. 列表推导式 vs 循环

python 复制代码
# 更简洁且通常更快
squares = [x**2 for x in range(10) if x % 2 == 0]

# 生成器表达式(节省内存)
squares_gen = (x**2 for x in range(10) if x % 2 == 0)

3. 内存泄漏:循环引用

python 复制代码
import gc

class Node:
    def __init__(self):
        self.parent = None
        self.children = []

# 创建循环引用
parent = Node()
child = Node()
parent.children.append(child)
child.parent = parent

# 手动打破循环引用或使用弱引用
import weakref
child.parent = weakref.ref(parent)

八、Pythonic 编程

1. 使用 enumerate

python 复制代码
# 不推荐
for i in range(len(items)):
    print(i, items[i])

# 推荐
for i, item in enumerate(items):
    print(i, item)

2. 使用 zip

python 复制代码
names = ["Alice", "Bob", "Charlie"]
ages = [25, 30, 35]

for name, age in zip(names, ages):
    print(f"{name} is {age} years old")

3. 上下文管理器

python 复制代码
# 传统方式
f = open("file.txt", "r")
try:
    data = f.read()
finally:
    f.close()

# 使用 with 语句
with open("file.txt", "r") as f:
    data = f.read()

九、常见错误与调试

1. TypeError: 'X' object is not callable

python 复制代码
# 通常是因为把变量名用作函数
list = [1, 2, 3]  # ❌ 覆盖了内置函数 list
# list( (4,5,6) )  # 错误!

lst = [1, 2, 3]   # ✅ 使用不同的变量名

2. AttributeError: module 'X' has no attribute 'Y'

python 复制代码
# 常见原因:
# 1. 拼写错误
# 2. 未正确导入子模块
# 3. 有同名的.py文件在搜索路径中

3. 使用调试工具

python 复制代码
import pdb

def buggy_function():
    pdb.set_trace()  # 设置断点
    # 调试代码
    # 常用命令:n(ext), s(tep), c(ontinue), l(ist), p(rint)

十、版本差异

Python 2 vs Python 3

python 复制代码
# 1. print 函数
print "Hello"  # Python 2
print("Hello")  # Python 3

# 2. 整数除法
3 / 2  # Python 2: 1, Python 3: 1.5
3 // 2  # 两者都是: 1

# 3. Unicode
str_type = type("hello")  # Python 2: <type 'str'>, Python 3: <class 'str'>
相关推荐
lead520lyq几秒前
Golang Grpc接口调用实现账号密码认证
开发语言·后端·golang
EQ-雪梨蛋花汤几秒前
【问题反馈】JNI 开发:为什么 C++ 在 Debug 正常,Release 却返回 NaN?
开发语言·c++
Blossom.118几秒前
从“金鱼记忆“到“超级大脑“:2025年AI智能体记忆机制与MoE架构的融合革命
人工智能·python·算法·架构·自动化·whisper·哈希算法
naruto_lnq1 分钟前
高性能消息队列实现
开发语言·c++·算法
charlie1145141911 分钟前
malloc 在多线程下为什么慢?——从原理到实测
开发语言·c++·笔记·学习·工程实践
CresCent_Charles3 分钟前
(源代码)CloudComPy+open3d实现点云配准项目(手动选点配准+ICP点云配准+误差显示)
python·点云·配准·点云配准
kyrie学java4 分钟前
SpringWeb
java·开发语言
写代码的【黑咖啡】6 分钟前
Python 中的 Gensim 库详解
开发语言·python
多米Domi0112 小时前
0x3f 第49天 面向实习的八股背诵第六天 过了一遍JVM的知识点,看了相关视频讲解JVM内存,垃圾清理,买了plus,稍微看了点确定一下方向
jvm·数据结构·python·算法·leetcode
饺子大魔王的男人2 小时前
Remote JVM Debug+cpolar 让 Java 远程调试超丝滑
java·开发语言·jvm