卡码笔记-最强八股文
首页
计算机基础
Python
C++
Java
Go
🔥大模型🔥
  • 大模型面经
  • Java面经
  • C++面经
大模型Github (opens new window)
代码随想录 (opens new window)
首页
计算机基础
Python
C++
Java
Go
🔥大模型🔥
  • 大模型面经
  • Java面经
  • C++面经
大模型Github (opens new window)
代码随想录 (opens new window)
  • 本栏必读

    • Python面试题专栏介绍
    • Python学习路线
    • Python零基础入门课
  • 基础语法

    • Python有哪些内置数据类型?
    • Python变量保存的是什么?
      • 简要回答
      • 详细回答
      • 知识拓展
    • 可变对象和不可变对象有什么区别?
    • is和==有什么区别?
    • Python的运算符有哪些?
    • Python条件判断和循环的常见写法与易错点
    • Python字符串为什么不可变?
    • Python列表和元组有什么区别?
    • Python字典和集合有什么区别?
    • Python切片和序列解包怎么用?
    • 列表、字典和集合推导式怎么写?
  • 函数、作用域与模块

  • 面向对象

  • 进阶语法与语言机制

# Python变量保存的是什么?变量、对象和引用有什么关系?

面试官问:“Python的变量里保存的是什么?a = b之后,修改b会影响a吗?”

很多录友会套用C语言的理解:变量是一块内存,赋值就是把值拷进去。用这个模型看Python,很快会遇到解释不了的现象,比如改了一个列表,另一个变量也跟着变。这道题要讲清楚的是:Python变量是名字,对象才是数据,赋值是在名字和对象之间建立绑定。

# 简要回答

Python中,变量是一个名字,它保存的是对某个对象的引用,而不是对象本身。对象是真正存在于内存中的数据,有自己的身份、类型和值。

执行a = b时,Python不会复制对象,而是让名字a也绑定到b当前指向的对象。之后如果通过b原地修改这个对象,比如对列表append(),a看到的也是修改后的结果;如果是让b重新绑定到别的对象,比如b = [],a不受影响。

所以,“修改b会不会影响a”,要先分清这是修改对象,还是让名字指向新对象。

# 详细回答

# 赋值做了什么:先有对象,再绑定名字

执行赋值语句时,Python先计算右侧表达式,得到一个对象,再把左侧的名字绑定到这个对象上:

price = 100
discount = price
price = 80
print(discount)  # 100
1
2
3
4

第一行,名字price绑定到整数对象100。第二行,discount绑定到price当前指向的同一个对象。第三行,price改为绑定整数对象80,discount仍然指向100。

赋值只改变名字的指向,不会修改原对象。 这也是为什么Python的名字没有固定类型:price可以先指向整数,再指向字符串,类型属于对象,不属于变量。

名字绑定与重新绑定

图左边是名字所在的命名空间,右边是对象。上半部分的重新绑定只改了箭头;下半部分的原地修改改的是对象,所以两个名字都能看到变化。

# 多个名字共享同一个可变对象

当共享的是可变对象时,绑定模型的影响就很明显:

cart = ["book"]
saved = cart
saved.append("pen")
print(cart)           # ['book', 'pen']
print(cart is saved)  # True
1
2
3
4
5

saved = cart没有生成新列表,cart和saved是同一个列表的两个名字。append()在原列表上添加元素,所以通过cart也能看到"pen"。is返回True,证明它们是同一个对象。

如果想要一个独立的列表,需要显式创建新对象,比如saved = cart.copy()或saved = list(cart)。

# 对象的三要素:身份、类型和值

每个对象都有三样东西:

身份:对象在生命周期内唯一且不变的标识,用id()查看,用is比较。在CPython中,id()返回的是对象的内存地址,但语言只保证它在对象存活期间唯一。

类型:决定对象支持哪些操作,用type()查看,创建后不会改变。

值:对象保存的数据。可变对象的值可以改,不可变对象的值不能改,这部分展开见《Python中的可变对象和不可变对象有什么区别?》。

名字本身不属于这三要素。同一个对象可以有零个、一个或多个名字指向它。

# del删除的是名字,不是对象

很多人以为del会直接销毁对象,其实它解除的是名字的绑定:

item = ["x"]
other = item
del item
print(other)  # ['x']
1
2
3
4

del item之后,名字item不再可用,但列表还被other引用,所以对象依然存在。对象什么时候被回收,由解释器的内存管理决定;在CPython中,主要依靠引用计数,当没有任何引用指向对象时,它会被回收。

# 知识拓展

面试官可能追问:

Q1:Python函数传参是值传递还是引用传递?

两个说法都不够准确,更准确的叫法是对象共享传递:调用函数时,形参绑定到实参指向的同一个对象。函数内原地修改可变对象会影响外部,重新绑定形参则不会。它和本文讲的赋值绑定是同一套规则。

Q2:a is b和a == b有什么区别?

is判断两个名字是否指向同一个对象,==判断两个对象的值是否相等。值相等的两个列表可以是不同对象。具体规则和常见误用见《is和==有什么区别?》。

Q3:为什么a = 256; b = 256时a is b可能是True?

在CPython中,-5到256的小整数会被预先创建并复用,所以两个名字可能指向同一个对象。这是实现层面的优化,换一个版本或实现结果可能不同。比较数值应该用==,不能依赖这种缓存。

Q4:Python代码运行时,名字存在哪里?

名字存在命名空间中,比如模块的全局命名空间、函数调用时的局部命名空间,可以近似理解为“名字到对象”的映射。代码在执行前会被编译成字节码,执行过程见《Python程序如何运行?》。

Last Updated: 10/13/2026, 5:57:00 PM

← Python有哪些内置数据类型? 可变对象和不可变对象有什么区别? →

评论

验证登录状态...

侧边栏 侧边栏
夜间模式 夜间
卡码简历 卡码简历
代码随想录 代码随想录
卡码投递表 卡码投递表🔥
2026实习校招群 2026群
添加客服微信 2026实习校招客服微信 PS:通过微信后,请发送姓名-学校-年级-2026实习/校招
支持卡码笔记 支持卡码笔记
鼓励/支持/赞赏Carl 卡码笔记赞赏码
1. 如果感觉本站对你很有帮助,也可以请Carl喝杯奶茶,金额大小不重要,心意已经收下
2. 希望大家都能梦想成真,有好的前程,加油💪