
哈喽,各位Python爱好者、编程新手小伙伴们!今天咱们来啃一个Python面试必考、开发必用、新手必懵的核心知识点——可变类型与不可变类型!
不管你是刚入门Python的小白,还是正在做PyQt5桌面开发、Web开发、数据分析的程序员,这个知识点都是绕不开的「基础地基」。很多时候我们写代码出现莫名其妙的BUG:函数传参改了原值、列表赋值互相影响、字典数据异常,90%都是因为没搞懂可变与不可变的本质区别!
更重要的是,在PyQt5桌面应用开发中,这个知识点直接决定你的界面数据绑定、状态管理是否稳定——比如界面中的输入框、列表控件、表格数据,用对类型能让程序流畅不崩溃,用错类型会导致界面卡顿、数据丢失、状态错乱!
今天这篇文章,我不仅会用最通俗、最直观的方式讲清两者的核心区别,还会直接上PyQt5精美可视化桌面工具,用图形界面让你亲手操作、直观看到两种类型的差异,代码完整可直接运行,界面精致高级、不透明超好看,功能拉满!全程干货无废话,看完彻底吃透,面试、开发直接拿捏!
不可变类型(Immutable)内存中的数据不允许被修改,一旦创建就固定不变;如果对变量重新赋值,会新开辟一块内存空间,变量指向新的内存地址。 ✅ 常见类型:int(整数)、float(浮点数)、str(字符串)、tuple(元组)、bool(布尔值)
可变类型(Mutable)内存中的数据可以直接修改,修改后变量指向的内存地址不变,不会创建新对象。 ✅ 常见类型:list(列表)、dict(字典)、set(集合)
不可变类型:改值=换新家;可变类型:改值=装修家,地址不变!
我为大家打造了一款高级不透明、超美观、功能完整的PyQt5工具,直接运行就能可视化对比两种类型的差异,包含:类型展示、修改测试、内存地址查看、结果输出四大功能!
# 安装依赖pip install pyqt5这部分负责创建主窗口、设置不透明效果、渐变样式、精致控件样式,让界面高级感拉满,同时初始化界面布局。
封装不可变类型(字符串、元组)和可变类型(列表、字典)的修改逻辑,实时打印内存地址、修改结果,直观展示差异。
按钮点击事件绑定,点击即可触发类型测试,把结果实时展示在界面文本框中,操作简单直观。
import sysfrom PyQt5.QtWidgets import *from PyQt5.QtCore import Qtfrom PyQt5.QtGui import QFont# 主窗口类classPythonTypeDemo(QMainWindow):def__init__(self): super().__init__() self.init_ui() # 初始化界面 self.set_style() # 设置高级样式# 1. 界面初始化(第一部分代码详解)definit_ui(self):# 窗口基础设置 self.setWindowTitle("Python 可变类型 VS 不可变类型 | 可视化工具") self.resize(800, 600)# 窗口不透明(核心:设置窗口透明度) self.setWindowOpacity(0.98)# 中心部件 + 主布局 central_widget = QWidget() self.setCentralWidget(central_widget) main_layout = QVBoxLayout(central_widget) main_layout.setSpacing(20) main_layout.setContentsMargins(40, 40, 40, 40)# 标题标签 title_label = QLabel("Python 可变类型 & 不可变类型 可视化测试") title_label.setAlignment(Qt.AlignCenter) title_label.setFont(QFont("微软雅黑", 16, QFont.Bold))# 功能按钮区域 btn_layout = QHBoxLayout() self.immutable_btn = QPushButton("测试 不可变类型(str/tuple)") self.mutable_btn = QPushButton("测试 可变类型(list/dict)") self.clear_btn = QPushButton("清空结果")# 设置按钮大小for btn in [self.immutable_btn, self.mutable_btn, self.clear_btn]: btn.setMinimumHeight(45) btn.setFont(QFont("微软雅黑", 11)) btn_layout.addWidget(self.immutable_btn) btn_layout.addWidget(self.mutable_btn) btn_layout.addWidget(self.clear_btn)# 结果展示文本框 self.result_text = QTextEdit() self.result_text.setFont(QFont("Consolas", 12)) self.result_text.setReadOnly(True) # 只读# 知识点说明标签 tip_label = QLabel("✅ 不可变类型:修改值=创建新对象,内存地址改变\n✅ 可变类型:修改值=原对象修改,内存地址不变") tip_label.setFont(QFont("微软雅黑", 11)) tip_label.setAlignment(Qt.AlignLeft)# 添加到主布局 main_layout.addWidget(title_label) main_layout.addLayout(btn_layout) main_layout.addWidget(tip_label) main_layout.addWidget(self.result_text)# 绑定按钮事件(第三部分代码详解) self.immutable_btn.clicked.connect(self.test_immutable) self.mutable_btn.clicked.connect(self.test_mutable) self.clear_btn.clicked.connect(self.result_text.clear)# 2. 全局精致样式设置(高级美观核心)defset_style(self): self.setStyleSheet(""" QMainWindow { background-color: #f7f8fa; } QLabel { color: #2c3e50; } QPushButton { background-color: #409eff; color: white; border: none; border-radius: 8px; padding: 5px 15px; } QPushButton:hover { background-color: #66b1ff; } QPushButton:pressed { background-color: #337ecc; } QTextEdit { background-color: white; border: 1px solid #dcdfe6; border-radius: 10px; padding: 15px; color: #303133; } """)# 3. 测试不可变类型(第二部分代码详解)deftest_immutable(self): self.result_text.clear() self.result_text.append("="*60) self.result_text.append("📌 测试:不可变类型(字符串str + 元组tuple)") self.result_text.append("="*60)# 测试字符串(不可变) s = "Hello" self.result_text.append(f"原始字符串:{s},内存地址:{id(s)}")# 尝试修改try: s[0] = "h"except TypeError as e: self.result_text.append(f"❌ 报错:{e}(不可变类型无法直接修改!)")# 重新赋值(创建新对象) s = "hello" self.result_text.append(f"重新赋值后:{s},内存地址:{id(s)}") self.result_text.append("👉 结论:字符串修改会创建新对象,地址改变!\n")# 测试元组(不可变) t = (1, 2, 3) self.result_text.append(f"原始元组:{t},内存地址:{id(t)}")try: t[0] = 10except TypeError as e: self.result_text.append(f"❌ 报错:{e}(元组不可修改!)") self.result_text.append("="*60) self.result_text.append("✅ 不可变类型总结:不能直接修改原数据,修改=新对象!\n\n")# 4. 测试可变类型(第二部分代码详解)deftest_mutable(self): self.result_text.clear() self.result_text.append("="*60) self.result_text.append("📌 测试:可变类型(列表list + 字典dict)") self.result_text.append("="*60)# 测试列表(可变) lst = [1, 2, 3] self.result_text.append(f"原始列表:{lst},内存地址:{id(lst)}")# 直接修改 lst[0] = 100 self.result_text.append(f"修改后列表:{lst},内存地址:{id(lst)}") self.result_text.append("👉 结论:列表修改原对象,内存地址不变!\n")# 测试字典(可变) d = {"name": "Python", "age": 10} self.result_text.append(f"原始字典:{d},内存地址:{id(d)}")# 直接修改 d["age"] = 20 d["gender"] = "男" self.result_text.append(f"修改后字典:{d},内存地址:{id(d)}") self.result_text.append("="*60) self.result_text.append("✅ 可变类型总结:直接修改原数据,地址不变!\n\n")# 程序入口if __name__ == "__main__": app = QApplication(sys.argv) window = PythonTypeDemo() window.show() sys.exit(app.exec_())内存机制区别(最核心)
常用类型分类✅ 不可变:int、float、str、tuple、bool✅ 可变:list、dict、set
报错特性不可变类型不能通过下标直接修改元素,会触发TypeError;可变类型无此限制。
函数传参区别
这篇干货你学会了吗?赶紧运行代码动手测试,彻底吃透Python核心基础!