python中的基础知识点-1

一、先明确:Python 数据类型的核心分类

Python 基本数据类型主要分两类:不可变类型 (创建后不能改内容)、可变类型(创建后能改内容),先记这个大框架,后续好理解:

类型分类 具体类型 特点
不可变类型 数字、字符串、元组 内容改不了,改就是新建
可变类型 列表、字典、集合 内容能直接增删改

如果从数据复杂度上来区分,又可以分为基本数据类型和复合数据类型

| 类型分类 | 具体类型 | 特点 |
| 基本数据类型 | 数字、字符串 | 结构简单,数据类型单一 |

复合数据类型 列表、字典、集合、元组 结构复杂,数据类型存在多样性

与C/C++的区别和联系,从上面可以看出来,python对基本数据类型做了很大的精简,不再对数字做出严格划分,如short long long long 以及有符号,无符号。

但是对复合数据类型却做了,很大的扩充,添加了很多属性,至于class,我们认为是一种特殊的用户自定义复杂类型(注意,我说的不是复杂数据类型,因为class还兼有方法,我认为不能单纯的认为是一种数据结构)。


二、逐个拆解:核心基本数据类型(用法 + 例子)

2.1、数字(Number)------ 用来做计算

包含整数(int)、浮点数(float)、布尔值(bool)(布尔值是特殊的整数:True=1,False=0)。

用法:

  • 定义:直接赋值,不用声明类型(Python 自动识别);
  • 操作:加减乘除、比较(> < ==)、取余(%)、幂运算(**)(这里需要区分c/c++中的^符号)等。

例子:

python 复制代码
# 整数
age = 18  # int类型
# 浮点数(带小数点)
height = 175.5  # float类型
# 布尔值(只有True/False)
is_adult = age >= 18  # bool类型,结果是True

# 常用计算
print(age + 2)  # 20(整数相加)
print(height * 2)  # 351.0(浮点数相乘)
print(10 % 3)  # 1(取余:10除以3余1)
print(2 **3)  # 8(幂运算:2的3次方)
2.2、字符串(String,str)------ 用来存文本

就是 "一串文字",用单引号' '、双引号" "或三引号''' '''包裹。

用法:

  • 定义:直接赋值文本;
  • 核心操作:拼接(+)、切片(取部分)、格式化(f-string)、查找 / 替换等。
  • 以及常见的join方法,这里需要非常注意,很多人误以为join也是一个关键字,其实本质上joinPython 字符串(str类型)专属的「内置方法」,不是关键字!下文代码中也可以看出,还需要关注join前还需要指定插入符。
  • 此处,可能还有有同学会问,不是说join是一种内置方法吗?为什么不需要实例对象,就可以调用?

例子:

python 复制代码
# 基础定义
name = "小明"  # str类型
intro = '我叫{},今年{}岁'.format(name, age)  # 老版格式化,使用format的内置方法
intro_new = f"我叫{name},今年{age}岁"  # f-string(最常用)
str1 = "".join(["Py", "thon", "教程"]) #此处join前用用""空字符代表,后面参数无间隙拼接
str2 = "-"join("2025","12","1") #此处得到的字符串为 2025-12-1

# 常用操作
print(name + "你好")  # 拼接:小明你好
print(name[0])  # 切片:取第一个字符"小"
print(len(name))  # 长度:2(统计字符数)len也是python内置的库函数,直接返回str的长度
print(name.replace("小", "大"))  # 替换:大明 #replace,是str内置的一种方法,存在两个参数,第一个参数是被替换值,第二个参数是,替换值

python中字符串高级用法

字符串类型 Python 2 中的定义 Python 3 中的定义 版本兼容范围
str 字节串(对应 Python3 的 bytes) Unicode 文本字符串(默认) Python 2.x / Python 3.0+
bytes 无此类型 字节串(二进制数据) Python 3.0+
unicode (现在基本不用) Unicode 文本字符串 无此类型(合并到 str) Python 2.0+;Python3.3 + 允许 u 前缀
basestring (现在基本不用了) str/unicode 的抽象基类 已移除 仅 Python 2.x

于是对于str类型的字符串,我们都已经很熟悉了,来看看byte类型的字符串是什么意思?

  1. str:Unicode 文本字符串(Python 3 默认字符串类型)
  • 定义 :表示Unicode 字符序列支持全球所有语言的字符,如中文、英文、符号等),是 Python 3 的默认字符串类型。

  • 表示方式 :用单引号'xxx'、双引号"xxx"、三引号'''xxx'''/"""xxx"""表示,不需要任何前缀

  • 版本支持 :从 Python 3.0 开始作为默认字符串类型,所有 Python 3 版本(3.0+)均兼容。

  • 示例

    python

    python 复制代码
    s1 = "Python"       # str类型
    s2 = "你好,世界"   # str类型(支持Unicode字符)
    s3 = '''多行
    字符串'''           # str类型
  1. bytes:字节串(二进制数据序列)
  • 定义 :表示原始二进制数据 (不是文本,是字节的序列),常用于文件读写、网络传输等场景。

  • 表示方式 :在字符串前加 b 前缀(如b'xxx'),只能包含 ASCII 范围内的字符(超出则需用转义符表示二进制值)。

  • 版本支持 :从 Python 3.0 开始支持,所有 Python 3 版本(3.0+)均兼容。

  • 示例

    python

    python 复制代码
    b1 = b"abc"        # bytes类型(ASCII字符)
    b2 = b"\xe4\xbd\xa0"  # bytes类型(转义表示非ASCII字符的二进制值)

这时又会有人会问,这个byte类型的字符,到底能起到什么作用。大家可能还记得C/C++中的char类型,通过格式控制符%d,是可以直接打印为数字的,赋值时char类型的变量,也可以直接赋值为数字常量。

python中的byte类型的字符串,和char比较类似。

Python 3 补充说明

  • strbytes 不能直接拼接,需通过 encode()(str→bytes)或 decode()(bytes→str)转换(使用内置方法的编码和解码方法):

    python

    复制代码
    s = "你好"
    b = s.encode("utf-8")  # str转bytes
    s2 = b.decode("utf-8") # bytes转str
2.3、 列表(List)------ 有序的 "杂货筐"

用**[]**包裹,能存任意类型的数据(数字、字符串、列表等),可修改

用法:

  • 定义:列表名 = [元素1, 元素2, ...]
  • 核心操作:增(append默认加在末尾处)、删(remove)、改(直接赋值)、查(索引)、切片。(增删改查切)

例子:

python 复制代码
# 基础定义
my_list = [18, "小明", 175.5, True]  # list类型,混合数据

# 常用操作
my_list.append("男")  # 新增元素:[18, "小明", 175.5, True, "男"]
my_list[1] = "小红"  # 修改元素:[18, "小红", 175.5, True, "男"]
my_list.remove(18)  # 删除元素:["小红", 175.5, True, "男"]
print(my_list[0])  # 查元素:小红
print(my_list[1:3])  # 切片:取第2-3个元素 [175.5, True]
2.4、 元组(Tuple)------ 有序的 "只读杂货筐"

用**()包裹,和列表类似,但不可修改**(创建后不能增删改),更安全。类似于只读

用法:

  • 定义:元组名 = (元素1, 元素2, ...)小括号可省略,但建议写);
  • 核心操作:只能查(索引 / 切片),不能改。

例子:

python 复制代码
# 基础定义
my_tuple = (18, "小明", 175.5)  # tuple类型

# 常用操作(只能查)
print(my_tuple[1])  # 查元素:小明
print(my_tuple[:2])  # 切片:(18, "小明")

# 尝试修改会报错(不可变的核心特点)
# my_tuple[1] = "小红"  # 报错:TypeError: 'tuple' object does not support item assignment

小结:关于切片语法的小结,语法中存在两个参数,被【】包括,两个参数中间使用:分隔开,其中第一个参数可以不写,不写就代表从第一个参数开始切片。写了第一个参数就是从该参数+1处开始切片

2.5、 字典(Dictionary,dict)------ 键值对 "对照表"

{键: 值}包裹,按 "键(key)" 找 "值(value)",可修改,像查字典一样(拼音→汉字)。

用法:

  • 定义:字典名 = {key1: value1, key2: value2, ...}(key 通常是字符串 / 数字,value 任意类型);
  • 核心操作:增(新增键值对)、删(del)、改(直接赋值)、查(按 key 找)。

例子:

python 复制代码
# 基础定义
person = {"name": "小明", "age": 18, "height": 175.5}  # dict类型

# 常用操作
person["gender"] = "男"  # 新增键值对:{"name":"小明", "age":18, "height":175.5, "gender":"男"}
person["age"] = 19  # 修改值:age变成19
del person["height"]  # 删除键值对:{"name":"小明", "age":19, "gender":"男"}
print(person["name"])  # 查值:小明
print(person.keys())  # 查所有键:dict_keys(['name', 'age', 'gender'])

这里del不是方法,而是一个关键字

2.6、 集合(Set)------ 无序的 "无重复集合"

{}包裹(注意和字典区分:集合只有元素,没有键值对),自动去重支持交集 / 并集等集合操作。

用法:

  • 定义:集合名 = {元素1, 元素2, ...}set(列表)
  • 核心操作:增(add)删(discard)、去重、找交集(&)/ 并集(|)。

例子:

python 复制代码
# 基础定义(自动去重)
my_set = {1, 2, 2, 3}  # set类型,结果是{1,2,3}

# 常用操作
my_set.add(4)  # 新增:{1,2,3,4}
my_set.discard(2)  # 删除:{1,3,4}

# 集合运算(交集/并集)
set1 = {1,2,3}
set2 = {3,4,5}
print(set1 & set2)  # 交集:{3}
print(set1 | set2)  # 并集:{1,2,3,4,5}
2.7、python这些特有特殊语法,"+"拼接字符串 和"+="

对熟悉C/C++的人看这段代码:

cpp 复制代码
int NumArray1[2] = {1,2};

int NumArray2[2] = {3,4};

int NumArray3[4] = NumArray1+NumArray2;

编译器会直接报错,不支持数组直接相加,其他类型如结构体也不支持,甚至数组都不支持整体赋值,但是结构体可以。class实例对象也不支持直接相加,但是同一个模板的实例对象可以直接赋值。

但是我们一直说python是一种易学语言。它提供了很多更偏向于日常生活中常用的语法,比如,你们公司再赶一个项目,大老板说,明天项目必须上线,人手不够,软件组先上,软件搞不定+硬件组,再搞不定运维+测试也一起上。一个组内有搞设计的,有管理的领导,有专门测试的,有协调项目进度的,映射到数据结构中,更像一些复杂数据结构。

python就很好的支持了,这种类似于口语化的语法。看下面一段代码

python 复制代码
# ✅ 1. 字符串拼接(最常用)
s1 = "Py" + "thon"
print(s1)  # 输出:Python

# ✅ 2. 列表拼接
lst1 = [1,2] + [3,4]
print(lst1)  # 输出:[1, 2, 3, 4]
#这里需要注意与内置方法append的区别

# ✅ 3. 元组拼接
t1 = (10,20) + (30,40)
print(t1)  # 输出:(10, 20, 30, 40)

# ✅ 4. 字节串拼接
b1 = b"abc" + b"def"
print(b1)  # 输出:b'abcdef'#注意这种拼接方法,也是非常独特,不被引号包围的不参与拼接

以下几点,需要特别注意:

(1)只有同类型的可以使用拼接运输符(不同类型的需要使用转换函数,强制转换类型)

(2)元组可以拼接,但是必须在定义时刻初始化(这段话,看起来很具有矛盾性,)

二、各数据类型「专属高效拼接技巧」(比运算符更实用)

+ 运算符适合少量数据拼接 ,如果需要拼接多个元素 / 大批量数据,推荐用各类型的专属方法,效率和可读性更优。

✅ 1. 字符串:3 种高效拼接(远超 + 的实用性)

字符串拼接是开发中最频繁的操作,这 3 种方法比 + 更常用:

str.join(可迭代对象) → 批量拼接(推荐)

分为3个部分,str必须被双引号包含,

接收可迭代对象 (列表、元组、生成器等),将所有元素用指定字符串(也就是str) 连接,批量拼接超高效

python

python 复制代码
# 用空字符串拼接(无缝连接)
res1 = "".join(["Py", "thon", "666"])
print(res1)  # Python666

# 用指定分隔符拼接
res2 = "-".join(["2025", "12", "31"])
print(res2)  # 2025-12-31

② f-string 格式化拼接 → 混合类型拼接(Python3.6+,最推荐)

完美解决「字符串 + 数字 / 变量」的拼接需求,语法简洁、可读性最强,支持任意数据类型混合拼接。

python

运行

python 复制代码
name = "Python"
version = 3.12
res = f"编程语言:{name},版本:{version}"
print(res)  # 编程语言:Python,版本:3.12

③ 格式化符 % / str.format() → 兼容式拼接

适合 Python 低版本,或批量格式化场景,也是混合类型拼接的常用方案。

python

运行

python 复制代码
# % 格式化
res1 = "数字:%d,浮点数:%.2f" % (10, 3.1415)
print(res1)  # 数字:10,浮点数:3.14

# format 格式化
res2 = "姓名:{},年龄:{}".format("小明", 18)
print(res2)  # 姓名:小明,年龄:18

✅ 2. 列表:2 个专属拼接方法

除了 +/+=,列表还有 2 个更灵活的拼接方法,适配不同场景:

list.extend(可迭代对象) → 批量追加(等价于 +=,更语义化)

直接将可迭代对象的所有元素追加到列表末尾,原地修改,效率极高。

python

运行

python 复制代码
lst = [1,2]
lst.extend([3,4])  # 等价于 lst += [3,4]
lst.extend((5,6))  # 支持传入任意可迭代对象
print(lst)  # [1,2,3,4,5,6]

list.append(元素) → 单个元素追加(注意和拼接区分)

⚠️ 易错点:append追加单个元素,不是拼接!如果传入列表,会把整个列表当成 1 个元素存入。

python

运行

复制代码
lst = [1,2]
lst.append(3)       # 追加单个元素 ✔
lst.append([4,5])   # 把列表当成1个元素存入 ❌
print(lst)  # [1,2,3,[4,5]]

✅ 3. 元组:特殊拼接补充

元组是不可变对象 ,所有拼接操作都会生成新元组,无原地修改方法(这两个方法需要特别注意);如果需要拼接单个元素,必须给元素加 ,(否则会被识别为普通数据类型)。

python

python 复制代码
# 正确:单个元素拼接(加逗号,标识为元组)
t2 = (1,2)
t3 = (3,)
t1 = t2+t3
print(t1)  # (1,2,3)
print(t2)  # (1,2)不会改变t2原本的值

# 错误:不加逗号,3是整数(非元组,类型不同)
t1 + (3)  # TypeError: can only concatenate tuple (not "int") to tuple

三、关键澄清:Python 「无拼接专用关键字」

✅ 结论重申

Python 的关键字列表中,不存在任何专门用于「拼接」的关键字比如 join/extend 是「方法名」,不是关键字)。

✨ 补充:Python 关键字是语言层面规定的特殊保留字(如 if/for/def/return),用于控制程序逻辑,而非数据操作;拼接属于「数据操作」,全部由运算符 / 内置方法实现。

✅ 易混淆点区分

很多人会把「拼接相关方法」误认成关键字,这里明确区分:

  • join:字符串的内置方法,不是关键字;
  • extend/append:列表的内置方法,不是关键字;
  • ✔ 真正的拼接核心:+/+=(运算符) + 各类型专属方法。

四、Python 拼接「高频易错点汇总」(避坑必看)

❌ 错误 1:不同类型直接用 + 拼接(切记)

python

python 复制代码
# 典型错误:字符串 + 整数
"num:" + 100  # 报错TypeError
# 正确写法:先类型转换
"num:" + str(100)

❌ 错误 2:列表用 append 做拼接

python

python 复制代码
# 错误:append追加列表,会嵌套
lst = [1,2]
lst.append([3,4])  # [1,2,[3,4]]
# 正确:用extend/+
lst.extend([3,4])  # [1,2,3,4]

❌ 错误 3:元组拼接单个元素不加逗号(前文已经强调了)

python

python 复制代码
# 错误:(3)是整数,不是元组
(1,2) + (3)  # 报错TypeError
# 正确:加逗号,标识元组
(1,2) + (3,)

❌ 错误 4:大批量字符串用 + 拼接

python

python 复制代码
# 低效:多次+拼接会生成多个新字符串,浪费内存
s = ""
for i in range(1000):
    s += str(i)  # 虽然Python做了优化,但仍不推荐
# 高效:用join批量拼接
s = "".join(str(i) for i in range(1000))

五、完整总结(精华提炼,快速查阅)

✅ 一、核心拼接运算符

  1. +:基础拼接,同类型序列可用,生成新对象;

  2. +=:增强拼接,原地修改(可变对象),效率更高。

✅ 二、各类型最优拼接方案

  1. 字符串 :少量拼接用+,混合类型用f-string,批量拼接用join()

  2. 列表 :少量拼接用+=,批量追加用extend(),单个元素用append()

  3. 元组 :仅用+拼接(生成新元组),单个元素拼接加,

  4. 字节串 :直接用+/+=即可。

✅ 三、核心规则

  1. ✔ 仅同类型序列可拼接;

  2. ✔ Python 无拼接关键字,拼接靠「运算符 + 方法」;

  3. ✔ 不可变对象(字符串、元组)拼接生成新对象,可变对象(列表)优先原地修改。

三、新手必记的核心要点

  1. 类型判断 :用type(变量)查看类型,比如type(18)<class 'int'>;type本身也是一个关键字
  2. 不可变 vs 可变
    • 不可变(数字 / 字符串 / 元组):改内容会生成新对象(比如name = "小明"name = "小红"是新建了字符串,不是改原来的);
    • 可变(列表 / 字典 / 集合):直接改内容,对象本身不变;
  3. 常用场景
    • 存单个数值 / 布尔 → 数字;
    • 存文本 → 字符串;
    • 存有序、可改的多个数据 → 列表;
    • 存键值对(比如用户信息:姓名→小明,年龄→18)→ 字典;
    • 存不重复的无序数据 → 集合;
    • 存不可修改的有序数据 → 元组。

四、与C语言和C++基础数据之间的差别

4.1、定义方式和书写规则之间的差异

有时候就是这样,如果没有C或C++基础,直接学习Python,反而还不容易出现一些记忆错乱,和肌肉记忆导致错误的地方。

1、千万不要被python中数据类型的英文名,干扰,如list 、truple、dictionary、set等干扰,记住非常重要的一条【所有python类型,包含基本数据和复合数据一律,不需要写数据类型

2、所有复合类型如 list 、truple、dictionary、set均不需要指定长度,这点需要记住,不要因为肌肉记忆,直接给这些数据类型定义一个长度,尤其是set,不注意的话,书写方式和数组特别像

3、python是不支持C和C++中的,数组,结构体,枚举。共用体的,此外python书写方式上也没有指针(只有self这种类指针的用法)(但是python依然是可以导入第三方包,来定义c中的数组和结构体,这是属于一些高阶用法,我们暂时不需要关注)

4、注意python所有复合数据类型,所有元素之间的分隔符都是","(注意是英文符号下的逗号),这点需要和C结构体定义中使用的";"作出区分

5、python中所有数据类型的所有成员,都是可以是任意基础数据类型。这句话有点拗口,解释就是python不像C或C++中的数组,要求成员的基本数据类型一致,可以是任意类型。

6、python中的所有复合数据类型,都可以使用以下形式进行检索:

符合类型变量名称+方括号+检索值:如

my_list[3]

my_truple[4]

my_dictionary["one"],注意这里的双引号也是必须得

my_set[4]

看到这里,我们似乎也就明白了,以前说的一句话,python是为了方便易学,易上手,维持牺牲一部分性能,而C/C++则是严谨的,但是比较难学,知识点零碎。

第6条,则说明了,python中的各种复合数据类型,结合了c、C++中数组和结构体的共同优点。c中的结构体,是不是不能使用for循环去遍历。但是python中除了字典,其他值都是可以使用for循环遍历的,这就是一种优势

4.3 、python的数据嵌套

我们知道,C或C++中是支持符合数据类型的嵌套的,如整形数组中嵌套整形数组,结构体中嵌套结构体,嵌套数组,、。

而Python的符合数据嵌套,则看起来更随意 ,方式也更加多样化从理论上来说,python是支持无限嵌套的,但是实际上没有编译器是支持无限嵌套的,也没有硬件是支持无限嵌套的

Python 嵌套的唯一语法约束是「集合 / 字典的键必须是可哈希类型」(不可变类型:int/str/tuple/frozenset;可变类型:list/dict/set 不可哈希),其余场景无限制。总结为图表,如下图:

类型 可哈希性 能否作为集合元素 / 字典键 能否被嵌套(作为值)
list ❌ 不可 ❌ 不能 ✅ 可以(任意位置)
tuple ✅ 可 ✅ 能 ✅ 可以
dict ❌ 不可 ❌ 不能 ✅ 可以(任意位置)
set ❌ 不可 ❌ 不能 ✅ 仅能作为其他类型的值(需用 frozenset)
frozenset ✅ 可 ✅ 能 ✅ 可以

说人话就是字典中,key值不能是list,也不能是dict 或set,但是注意常量(数字,字符)都是可以作为dict的key,也可以作为set的元素

4.3.1、什么是可哈希值

只有先了解这一点,才可以理解嵌套。

"可哈希" 是 Python 中对不可变对象的一种特性描述:如果一个对象在其生命周期内哈希值(hash value)永不改变 ,且能通过 __hash__() 方法返回唯一的整数哈希值,同时支持通过 __eq__() 方法判断是否相等,那么这个对象就是「可哈希的」。

简单说:可哈希 = 不可变 + 能生成唯一哈希值 + 可比较相等性

4.3.2 实际案例讲解嵌套-同类型嵌套

首先同类型进行嵌套是最简单的。

list内嵌套list:
python 复制代码
# 基础:二维列表(类比 C 的 int arr[2][3])
matrix = [
    [1, 2, 3],  # 内层列表(行)
    [4, 5, 6]   # 内层列表(行)
]
# 访问:和 C 多维数组语法一致(索引从 0 开始)
print(matrix[0][1])  # 2(第一行第二列)

# 进阶:三维列表(无限嵌套)
cube = [
    [[1, 2], [3, 4]],  # 第一层
    [[5, 6], [7, 8,9]]   # 第二层,注意这里第二层的第二个list中,包含了3个元素
]
print(cube[1][0][1])  # 6(第二层、第一行、第二列)

# 动态修改(C 需手动扩容,Python 一键搞定)
matrix.append([7, 8, 9])  # 新增一行 → [[1,2,3],[4,5,6],[7,8,9]]
matrix[1][2] = 10         # 修改元素 → [[1,2,3],[4,5,10],[7,8,9]]

但是注意:

1:、一般我们不建议>2维的数组,代码中也可以看出来,查找时是非常混乱的。

2、每一个最小List的元素数量不是固定不变的

字典嵌套字典(dict in dict)------ 类比 C/C++ "结构体嵌套结构体"
python 复制代码
# 基础:二级字典(用户信息)
user = {
    "name": "小明",
    "age": 18,
    "address": {  # 内层字典(地址结构体)
        "city": "北京",
        "street": "朝阳路",
        "zip": 100000
    }
}
# 访问:通过键逐层取值
print(user["address"]["city"])  # 北京

# 进阶:三级字典(系统配置)
config = {
    "server": {
        "ip": "127.0.0.1",
        "port": 8080,
        "timeout": {  # 第三层字典
            "connect": 5,
            "read": 10
        }
    }
}
print(config["server"]["timeout"]["read"])  # 10

# 动态增删内层字典
user["address"]["district"] = "朝阳区"  # 新增地址字段
del config["server"]["timeout"]["connect"]  # 删除字段

这里关注一下,(1)字典读取的方式,和字典缩进。(2)因为上面说的字典的key值必须是可哈希值,所以被嵌入的字典都被安排在了value的位置

truple元组嵌套元组

4.4、嵌套class的实例对象

先看下面一段代码

python 复制代码
class Fruit:
    def __init__(self, name, price):
        self.name = name
        self.price = price

fruits = [Fruit("apple", 5), Fruit("banana", 3), Fruit("cherry", 7)]
# key=lambda x: x.price:用Fruit对象的price属性作为排序依据
fruits.sort(key=lambda x: x.price)
print([f.name for f in fruits])  # 输出:['banana', 'apple', 'cherry'](价格从低到高)

这里可以看出来,这里将class实例对象作为list的元素,这里又引申出两个概念,匿名对象和显示对象。

匿名对象,即没有名字的对象(C++中通过vector也可以实现匿名对象的创建)

4.5、python中的数据类型,兼有方法

学到这里,看了这么多代码,我们也看出来了python这些复合数据类型,兼有方法,也就是函数的性质。和c++中的对象一样,可以通过 . 来调用函数。

如果从复合类型数据,能调用方法的属性来看,这是有点类似class实例化的特征了

复合数据可调用的方法

数据类型 方法名称 功能详细说明 典型应用场景示例
列表 (list) .append(x) 列表末尾添加单个元素 x 动态收集用户输入的数据
列表 (list) .extend(iterable) 将可迭代对象的所有元素追加到列表末尾 合并两个列表
列表 (list) .pop([i]) 移除并返回指定索引 i 的元素(无参数时默认最后一个) 实现栈结构的弹出操作
列表 (list) .sort(key=None, reverse=False) 对列表原地排序,key 指定排序依据,reverse=True 为降序 数据统计前的排序
列表 (list) .reverse() 原地反转列表元素顺序 需要倒序遍历的场景
extend()参数必须是可迭代的对象,即list,truple,set(注意dict是不能被添加到list中去的),不会改变添加list的类型(即依然保持list),被添加对象也不会改变自身数据属性 append则是添加单个对象,可以是常量和字符,也可以是其他基本数据中的一个元素,甚至是class实例对象所引用的属性。 pop方法,则是弹出该元素,会改变list本身的数据结构,其实更可以理解为删除。 sort和reverse方法都是排序函数,sort函数存在两个参数 key,和reserve两个参数。从本质上来说,并不是两个参数,而是两个表达式:以下是sort()的具体方法: python lst = ["apple", "banana", "cherry", "date"] lst.sort(key=len, reverse=True) print(lst) # 输出:['cherry', 'banana', 'apple', 'date'](长度从长到短) key是指定排序的方式,reverse=True是默认升序,reserve=false
字典 (dict) .keys() 返回字典所有键的视图对象(可迭代) 遍历字典的键
字典 (dict) .values() 返回字典所有值的视图对象(可迭代) 遍历字典的值
字典 (dict) .items() 返回键值对元组的视图对象(可迭代) 同时遍历键和值
字典 (dict) .get(key[, default]) 安全获取键对应的值,若键不存在则返回 default(默认 None) 防止 KeyError 异常
字典 (dict) .update(other) 用另一个字典或键值对更新当前字典 合并配置参数
字符串 (str) .lower() 返回字符串的小写形式 用户输入标准化
字符串 (str) .upper() 返回字符串的大写形式 标题格式化
字符串 (str) .split(sep=None, maxsplit=-1) 按分隔符 sep 分割字符串为列表(maxsplit 限制分割次数) 解析 CSV 数据
字符串 (str) .join(iterable) 用字符串连接可迭代对象中的元素 拼接路径、URL 参数
字符串 (str) .replace(old, new[, count]) 替换字符串中 old 子串为 new,count 限制替换次数 文本清理、数据预处理
集合 (set) .add(x) 向集合中添加元素 x(若已存在则无操作) 去重收集数据
集合 (set) .remove(x) 移除元素 x,若不存在则抛出 KeyError 精确删除特定元素
集合 (set) .discard(x) 移除元素 x,若不存在则不抛异常 安全删除元素
集合 (set) .union(other) / ` 返回当前集合与 other 的并集
集合 (set) .intersection(other) / & 返回当前集合与 other 的交集 寻找共同元素
元组 (tuple) .count(x) 统计元组中元素 x 出现的次数 数据分析
元组 (tuple) .index(x[, start[, end]]) 返回元素 x 首次出现的索引,可指定搜索范围 查找特定值位置

五、函数定义的区别

5.1、定义返回类型的区别

C或C++,需定义返回值类型

复制代码
// 格式:返回值类型 函数名(参数类型1 参数名1, 参数类型2 参数名2) { 函数体 }
int add(int a, int b) {  // 必须声明:返回值类型+参数类型
    return a + b;
}
  • 必须写返回值类型 (无返回值用void);
  • 必须写参数类型 + 参数名
  • 函数体必须用{}包裹,结尾可加分号(C++ 允许,C 不强制)。

python,不需要定义返回值类型,使用关键字def,形参后的括号后加上:

复制代码
# 格式:def 函数名(参数名1, 参数名2): 函数体(缩进)
def add(a, b):  # 无需声明任何类型
    return a + b
  • def关键字开头,无返回值类型(返回值类型由实际返回值决定);
  • 参数仅写参数名 ,无需指定类型,小括号后必须加上":";
  • 函数体靠缩进 区分(不用{}),结尾无分号。

5.2、一个靠"{}+;"(;并不是必须得)代表函数结束,一个靠缩进(identation)规则代表函数体结束

先详细介绍一下python的缩进:

Python 中的缩进 是python中语法级别的核心规则,是必须需要遵守的规则,核心规则总结如下:

记住「"冒号 + 4 个空格" 触发缩进,回归外层结束缩进,不使用空格和 Tab混用」,就能避免 99% 的缩进错误。

六、正常语句和空语句的区别

6.1 正常语句的区别

此外还有一点非常容易引起错误,大家都知道,python一行只写一条语句,然后按下回车换行键,继续编写下一条语句,编译器也会根据读取到的回车换行键,认定这条语句结束。即语句结束后,不需要强制写";"

但是必须要知道以下几点:

(1)python本身的语法并没有删除";" 只要你愿意,你在每行加上 ; 或部分语句加上都可以

(2)必须要加的情况,如果在一行中,写多条语句

小结,python判断语句结束,优先根据回车换行键判断,同时兼容;

6.2 空语句的区别和联系

对比维度 C/C++ 空语句 Python 空语句
核心写法 单独的; pass(推荐)或"..."
语法本质 语句结束符单独存在,代表 "无执行逻辑" 显式关键字占位,填补 "必须有代码块" 的语法要求
代码块 vs 语句 {}是空代码块,;是空语句(效果等价) 无 "空代码块" 概念 ,缩进内必须有pass/...
错误场景 少写;会编译报错(比如for循环) pass会语法报错(比如空函数)
可读性 ;易被忽略(比如while(1);),推荐用{} pass/...语义明确,一眼看出是 "空逻辑"

七、C++中Class的定义和Python中定义的区别和联系

7.1、先从最基本的定义说起

先看以下两段代码:分别为C++定义模板类,和Python定义模板类

代码段1:C++代码

cpp 复制代码
#include <string>
using namespace std;

class Car {
private:  // 默认private,显式声明更清晰
    string brand;  // 必须声明类型(string)
    int price;     // 必须声明类型(int)
public:
    // 成员方法声明(需指定参数/返回值类型)
    Car(string b, int p);  // 构造函数声明
    void run();            // 普通方法声明
    int get_price();       // 普通方法声明
};

// 源文件(类实现)
// 构造函数实现(需绑定类名)
Car::Car(string b, int p) {
    brand = b;
    price = p;
}

void Car::run() {
    cout << brand << " is running" << endl;
}

int Car::get_price() {
    return price;
}

代码段2:Python代码

python 复制代码
class Car:
    # 类属性(无需声明类型)
    category = "automobile"
    
    # 构造方法(无需声明参数/返回值类型)
    def __init__(self, brand, price):
        # 实例属性(动态绑定,无需提前声明)
        self.brand = brand
        self.price = price
    
    # 普通方法(self是隐含的实例引用,无需声明类型)
    def run(self):
        print(f"{self.brand} is running")
    
    def get_price(self):
        return self.price

相同点:

(1)基本的结构框架都是一样的,都包含属性和方法,

(2)都采取class作为关键字,来定义类

(3)都具有初始化函数

实现细节上,有一些不同:

首先说一些:通用的不同,方法和属性都不需要指定类型,都不需要使用{},而是使用缩进,这些都不需要多说

(1)一个初始化函数,C++是与类名相同的函数(不写返回值类型),Python是__init__()函数来执行初始化

(2)python,是存在一个默认形参self(注意这个self不是python的关键字,但是大家一般都这么写

(3)函数,也就是方法定义的地方,C++一般建议是写在class类模板的外面,且使用:类模板名称::函数名称(形参),来定义。而python则不需要这样的写法,利用缩进规则,写在定义时即可

(4)C++中存在3个关键字public,private,和protect,python没有这样的规则

7.2 、类实例化的区别和联系

C++实例化,采取 类模板名 + 实例名+(实参)或者使用new,以7.1中的代码为例:

Car SUV_1("星愿",30000);或者 Car *SUV = new Car("星愿",30000);

Car SUV_2("五菱Mini",25000);或者 Car *SUV = new Car("五菱Mini",25000);

而python则是采取了,另外一种方式:实例化名= 类模板名称(形参),

SUV_1 = Car ("星愿",30000)

SUV_2 = Car("五菱Mini",25000)

7.3 python与C++深层次Class的用法

7.3.1. 初始化的区别

(1)C++ 的初始化

C++ 的初始化分为构造函数初始化列表,规则严格且多态不生效:

  • 必须显式定义构造函数(默认生成无参构造、拷贝构造等,C++11 后支持默认构造=default);
  • 支持初始化列表(优先于构造函数体执行,用于初始化 const 成员、引用成员、父类成员);
  • 构造函数不能返回值,且编译期确定调用哪个构造函数;
  • 构造函数中多态不生效(子类构造时先调用父类构造,此时子类对象未完全创建,虚函数不会调用子类实现);
  • 支持拷贝构造移动构造(C++11 新增),用于对象拷贝 / 移动场景。

示例代码:

cpp

cpp 复制代码
#include <iostream>
using namespace std;

class Parent {
public:
    Parent(int a) : m_a(a) { // 初始化列表
        cout << "Parent构造" << endl;
    }
private:
    int m_a;
};

class Child : public Parent {
public:
    // 必须通过初始化列表调用父类构造,即在构造函数的:后直接调用父类的构造函数
    Child(int a, string b) : Parent(a), m_b(b) { 
        cout << "Child构造" << endl;
    }
private:
    const string m_b; // const成员必须在初始化列表初始化
};

int main() {
    Child c(10, "test"); //这里将child实例化,并将父类people中的实参传递进去
    return 0;
}
(2)Python 的初始化

Python 的初始化是分层执行的,__init__并非真正的构造函数:

  • 真正的构造函数是__new__(负责创建对象实例,返回实例对象),__init__是初始化函数(接收__new__创建的实例,进行属性初始化);
  • 无需显式调用父类初始化(可通过super().__init__()主动调用),支持动态传递参数;
  • 初始化时可动态添加属性(即使不在__init__中定义,后续也可通过obj.attr = value添加);
  • 支持默认参数、关键字参数,初始化逻辑更灵活;
  • 无专门的拷贝构造 / 移动构造,对象拷贝通过copy模块实现(浅拷贝copy.copy()、深拷贝copy.deepcopy())。

示例代码:

python

python 复制代码
class Parent:
    def __init__(self, a):
        self.a = a
        print("Parent初始化")

class Child(Parent):
    def __init__(self, a, b):
        super().__init__(a) # 主动调用父类初始化
        self.b = b
        print("Child初始化")

# 创建实例
C = Child(10, "test")
# 动态添加属性,这里给实例对象,添加了一个变量c,或者属性c
C.c = 20
print(C.a, C.b, C.c)

以上代码中,可以看出python中,

(1)继承写法和C++很不一样(语法上),写在子类名称后的括号里面。

(2)从此处还有一个非常重要的特性,即通过实例对象,还能添加属性。被添加的属性只属于实例C,而通过child模板创建的其他实例对象,则不会存在这个属性

(3)和C++不一样的地方在于,对属性赋值,C++是可以直接利用初始化列表实现,而python则只能使用赋值语句实现

(4)子类中如何实现父类初始化,python使用super()init(形参)来实现,(这里有必要多说一句,__是两个下划线,这类写法目前我所知道的也是python中独有的)

(4.1)、super()是python内部的一个内置class(也就是build-in class)

(4.2)、如果子类存在多个父类,或者存在多重继承的情况下,如何区别调用哪一个父类的初始化方法,这里又牵扯出MRO链条。

(4.3)、详细解释MRO链条

初始化核心差异总结
特性 C++ Python
真正构造函数 构造函数(编译期确定) __new__(运行时执行)
初始化逻辑 初始化列表(优先)+ 构造函数体 __init__(初始化实例属性)
父类初始化 必须在初始化列表显式调用 可通过super()主动调用,可选
动态属性添加 不支持(编译期固定成员) 支持(运行时动态添加)
拷贝 / 移动构造 原生支持(拷贝 / 移动语义) 无原生支持,依赖copy模块
多态生效 构造函数中多态不生效 __init__中可调用子类重写方法

7.3.2、继承的区别

(1)C++ 的继承

C++ 继承是静态编译期继承,支持多继承和访问权限控制,规则严格:

  • 支持多继承 (一个子类可继承多个父类),但会带来菱形继承问题(需通过virtual虚继承解决);
  • 继承权限控制:public/protected/private继承(影响父类成员在子类中的访问权限);
  • 虚继承:用于解决多继承的菱形问题,确保父类只被初始化一次;
  • 多态实现:基于虚函数virtual关键字),通过虚函数表(vtable)实现运行时多态;
  • 子类不能新增父类没有的虚函数(编译期确定虚函数表);
  • 支持纯虚函数virtual void func() = 0;),用于定义抽象类(不能实例化)。

示例代码(多继承 + 虚继承):

cpp 复制代码
#include <iostream>
using namespace std;

// 虚基类
class Base {
public:
    Base() { cout << "Base构造" << endl; }
    virtual void show() = 0; // 纯虚函数,抽象类
};

class A : virtual public Base { // 虚继承
public:
    void show() override { cout << "A::show" << endl; }
};

class B : virtual public Base { // 虚继承
public:
    void show() override { cout << "B::show" << endl; }
};

// 多继承
class C : public A, public B {
public:
    void show() override { cout << "C::show" << endl; } // 重写虚函数
};

int main() {
    C c;
    c.show(); // 调用C::show
    Base* ptr = &c;
    ptr->show(); // 多态:调用C::show
    return 0;
}
(2)Python 的继承

Python 继承是动态运行时继承,支持多继承和灵活的方法解析,无严格权限控制:

  • 支持多继承 (一个子类可继承多个父类),通过 **MRO(方法解析顺序)** 解决菱形继承问题(class.__mro__可查看顺序);
  • 无继承权限控制(仅通过属性命名规范区分公开 / 私有,无编译期限制);
  • 多态实现:无需关键字,子类重写父类方法即可实现多态(运行时动态绑定);
  • 支持动态继承 (运行时可修改类的父类,如Child.__bases__ = (Parent1, Parent2));
  • 支持抽象类 (通过abc模块的ABCMeta@abstractmethod装饰器实现);
  • 支持Mixin 模式(一种特殊的多继承,用于复用功能,不单独实例化);
  • super()函数:基于 MRO 顺序查找父类方法,而非直接调用父类。

示例代码(多继承 + MRO):

python

python 复制代码
class Base:
    def show(self):
        print("Base::show")

class A(Base):
    def show(self):
        print("A::show")

class B(Base):
    def show(self):
        print("B::show")

# 多继承
class C(A, B):
    pass

# 查看MRO顺序
print(C.__mro__) # (<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.Base'>, <class 'object'>)

c = C()
c.show() # 按MRO调用A::show

# 动态修改父类
C.__bases__ = (B, A)
print(C.__mro__) # 父类顺序改变
c.show() # 调用B::show
继承核心差异总结
特性 C++ Python
多继承支持 支持,存在菱形继承问题(需虚继承解决) 支持,通过 MRO 解决菱形继承问题
继承权限控制 支持(public/protected/private 继承) 不支持(无编译期权限限制)
多态实现 基于 virtual 虚函数 + 虚函数表 基于运行时动态绑定,无需关键字
动态修改父类 不支持(编译期固定继承关系) 支持(修改__bases__属性)
抽象类实现 基于纯虚函数(virtual ... = 0 基于abc模块(@abstractmethod
方法解析顺序 编译期确定,多继承需手动处理 运行时 MRO 顺序,自动解析
Mixin 模式 无原生支持(可通过多继承模拟) 原生支持(常用功能复用方式)
父类方法调用 直接通过父类名调用(如Parent::func() 通过super()基于 MRO 调用

3. 属性读写权限的区别

(1)C++ 的属性权限

C++ 的属性权限是编译期严格控制,通过访问修饰符限制,无法绕过:

  • 访问修饰符:public(公开,任意位置可访问)、protected(保护,子类 + 本类可访问)、private(私有,仅本类可访问);
  • 权限是编译期强制限制:若试图访问 private 成员,编译器直接报错,无法运行;
  • 友元机制:friend关键字可突破权限限制(友元函数 / 友元类可访问类的 private/protected 成员);
  • const 成员:const修饰的成员变量必须在初始化列表初始化,且只能读不能写
  • 静态成员:static修饰的成员属于类本身,而非实例,可通过类名直接访问

示例代码:

cpp

cpp 复制代码
#include <iostream>
using namespace std;

class Test {
public:
    Test(int a) : m_private_a(a), m_protected_b(10) {}
    static int m_public_c; // 静态公开成员

    void show() {
        cout << m_private_a << endl; // 本类可访问private成员
    }

    // 友元函数声明
    friend void friendFunc(Test& t); /**这里注意友元函数的形参,必须是需要绑定的CLASS类型的引 用,从另外一个方面来理解,就是friend,就是告诉编译器,这里的函数形参**/

private:
    int m_private_a; // 私有成员

protected:
    int m_protected_b; // 保护成员
};

int Test::m_public_c = 20; // 静态成员初始化,

// 友元函数:可访问private/protected成员
void friendFunc(Test& t) {
    cout << t.m_private_a << " " << t.m_protected_b << endl;
}

class ChildTest : public Test {
public:
    ChildTest(int a) : Test(a) {}
    void showProtected() {
        cout << m_protected_b << endl; // 子类可访问protected成员
        // cout << m_private_a << endl; // 编译报错:无法访问private成员
    }
};

int main() {
    Test t(5);
    t.show();
    cout << Test::m_public_c << endl; // 访问静态公开成员,注意这里class的静态成员,引用与初始化 Test::m_public_c
    friendFunc(t); // 友元函数访问私有/保护成员

    ChildTest ct(8);
    ct.showProtected();
    return 0;
}
(2)Python 的属性权限

Python 的属性权限是约定俗成 ,无编译期强制限制,通过特殊机制实现 "伪私有"

  • 无严格访问修饰符:通过命名规范区分:
    • 公开属性:普通命名(如attr),任意位置可访问;
    • 保护属性:单下划线开头(如_attr),约定子类可访问,外部不建议访问(但可直接访问);
    • 私有属性:双下划线开头(如__attr),通过 ** 名称改写(name mangling)** 实现伪私有(实际变为_类名__attr,仍可绕过访问);
  • 属性读写控制:通过属性装饰器@property@attr.setter@attr.deleter)实现灵活的读写权限控制(如只读、只写、自定义校验逻辑);
  • 动态属性拦截:通过__getattr____setattr____delattr__方法,可拦截所有属性的读写 / 删除操作,实现自定义逻辑;
  • 无友元机制:无法通过特殊关键字突破属性权限约定;
  • 静态成员:通过@staticmethod(静态方法)、@classmethod(类方法)实现,静态属性直接定义在类中。

示例代码:

python

python 复制代码
class Test:
    m_public_c = 20 # 静态公开属性

    def __init__(self, a):
        self.attr = a # 公开属性
        self._attr = 10 # 保护属性(约定)
        self.__attr = 20 # 私有属性(名称改写)

    # 属性装饰器:只读属性
    @property
    def read_only_attr(self):
        return self.attr + 10

    # 属性装饰器:可写属性(带校验)
    @property
    def write_attr(self):
        return self._attr

    @write_attr.setter
    def write_attr(self, value):
        if isinstance(value, int):
            self._attr = value
        else:
            raise ValueError("必须是整数")

    # 拦截属性访问
    def __getattr__(self, name):
        return f"属性{name}不存在"

class ChildTest(Test):
    def show(self):
        print(self._attr) # 子类可访问保护属性
        # print(self.__attr) # 直接访问报错
        print(self._Test__attr) # 绕过名称改写,访问私有属性

# 实例化
t = Test(5)
print(t.attr) # 访问公开属性
print(t._attr) # 访问保护属性(不建议,但可行)
print(t._Test__attr) # 绕过访问私有属性
print(t.read_only_attr) # 访问只读属性
# t.read_only_attr = 100 # 报错:无法修改只读属性

t.write_attr = 30 # 修改可写属性
print(t.write_attr)

# 访问不存在的属性(触发__getattr__)
print(t.xxx)

ct = ChildTest(8)
ct.show()
属性权限核心差异总结
特性 C++ Python
访问修饰符 原生支持(public/protected/private) 无原生支持,依赖命名规范(_/__)
权限强制程度 编译期强制限制(报错无法运行) 运行时约定俗成(可绕过)
友元机制 支持(突破权限限制) 不支持
属性读写控制 需通过 get/set 方法实现 支持@property装饰器,灵活控制
动态属性拦截 不支持(编译期固定成员) 支持(__getattr__等魔法方法)
私有属性实现 真正私有(无法绕过) 伪私有(名称改写,可绕过)
const 只读属性 原生支持(const关键字) 需通过@property实现(无 setter)

4. C++ class 有而 Python 没有的特性

C++ 的 class 存在不少 Python 不具备的特性,核心是基于静态编译和严格封装的设计:

  1. 严格的访问权限控制
  • C++ 的public/protected/private是编译期强制限制,private 成员无法被外部访问(友元除外),而 Python 仅为约定,无强制约束;
  • 继承权限控制(public/protected/private 继承):可改变父类成员在子类中的访问权限,Python 无此概念。
  1. 虚函数与虚函数表
  • C++ 通过virtual关键字实现虚函数,编译期生成虚函数表(vtable),运行时通过 vtable 找到子类实现,实现高效多态;
  • Python 无虚函数概念,多态基于运行时动态绑定,效率低于 C++ 的虚函数表。
  1. 纯虚函数与抽象类(原生支持)
  • C++ 可直接通过virtual void func() = 0;定义纯虚函数,生成抽象类(无法实例化),无需额外模块;
  • Python 需依赖abc模块实现抽象类,非原生支持。
  1. 构造函数初始化列表
  • C++ 的初始化列表优先于构造函数体执行,可初始化 const 成员、引用成员、父类成员,Python 无对应的语法(__init__仅为初始化,无法初始化 const 类似的不可变成员)。
  1. 拷贝构造与移动构造(原生语义)
  • C++ 原生支持拷贝构造(Class(const Class& other))和移动构造(Class(Class&& other)),分别对应对象的拷贝和移动语义,效率更高;
  • Python 无原生拷贝 / 移动构造,需通过copy模块实现,效率较低。
  1. 友元机制
  • C++ 的friend关键字可让外部函数 / 类访问类的私有 / 保护成员,用于特殊场景(如运算符重载),Python 无此机制。
  1. 模板类(泛型编程)
  • C++ 的template关键字支持模板类,可实现编译期泛型编程(类型无关的代码),如std::vector<T>
  • Python 本身是动态类型,无需模板类即可实现泛型功能,无对应的语法。
  1. const 成员与 const 成员函数
  • C++ 的const关键字可修饰成员变量(只读,必须初始化列表初始化)和成员函数(void func() const,保证不修改成员变量);
  • Python 无原生 const 语法,只读属性需通过@property模拟,无法保证成员函数不修改属性。

5. Python class 有而 C++ 没有的特性

Python 的 class 基于动态特性,拥有不少 C++ 不具备的灵活特性:

  1. 类本身是对象(元类)
  • Python 的 class 是type的实例(元类的对象),可动态修改类的属性 / 方法(如Class.attr = valueClass.__bases__ = (Parent,) );
  • C++ 的 class 是编译期的类型定义,不是对象,无法动态修改。
  1. 动态属性与方法
  • Python 的实例和类都可在运行时动态添加 / 删除属性 / 方法(如obj.attr = valuedef func(): pass; Class.func = func);
  • C++ 的类成员在编译期固定,无法动态增删。
  1. 属性装饰器(@property
  • Python 的@property装饰器可将方法伪装成属性,灵活实现读写权限控制、数据校验、懒加载等功能;
  • C++ 需通过手动编写 get/set 方法实现类似功能,语法繁琐。
  1. 魔法方法(特殊方法)
  • Python 的 class 支持大量魔法方法(如__init____str____getattr____add__等),可拦截对象的各类操作(属性访问、运算符重载、序列化等);
  • C++ 仅支持部分运算符重载,无类似的统一魔法方法体系。
  1. MRO 方法解析顺序
  • Python 的多继承通过 MRO(C3 算法)自动解决菱形继承问题,无需手动处理;
  • C++ 的多继承需通过虚继承手动解决菱形继承问题,语法复杂。
  1. 动态继承(修改__bases__
  • Python 可在运行时动态修改类的父类(Class.__bases__ = (Parent1, Parent2)),改变继承关系;
  • C++ 的继承关系在编译期固定,无法修改。
  1. Mixin 模式(原生支持)
  • Python 常用 Mixin 模式实现功能复用(如class MyClass(Parent, Mixin1, Mixin2)),Mixin 类不单独实例化,仅提供功能;
  • C++ 无 Mixin 的原生概念,需通过多继承模拟,灵活性不足。
  1. 无需显式声明成员变量
  • Python 的 class 无需提前声明成员变量,在__init__中直接赋值即可,甚至可在后续动态添加;
  • C++ 的 class 必须提前声明成员变量(public/protected/private),否则编译报错。
  1. 元类(Metaclass)
  • Python 的元类(如type、自定义元类)可控制类的创建过程,实现类的个性化定制(如自动添加方法、校验类的结构);
  • C++ 无元类概念,无法干预类的编译创建过程。

三、 核心差异总结

对比维度 C++ class 特性 Python class 特性
本质 静态类型,编译期类型检查 动态类型,运行时动态绑定
初始化 构造函数 + 初始化列表,const / 引用必须初始化列表 __new__(创建)+ __init__(初始化),动态添加属性
继承 多继承(需虚继承解决菱形问题),继承权限控制 多继承(MRO 自动解析),动态修改父类
多态 基于 virtual 虚函数 + 虚函数表 基于运行时动态绑定,无需关键字
属性权限 public/protected/private(编译期强制) 命名规范(_/__)+ @property(约定)
独有的特性 初始化列表、友元、模板类、const 成员、虚函数 元类、魔法方法、动态属性 / 继承、@property、Mixin
灵活性 低(编译期固定,规则严格) 高(运行时动态,灵活扩展)
效率 高(编译期优化,虚函数表高效) 较低(动态绑定,额外开销)
抽象类 纯虚函数原生支持 依赖abc模块实现

7.4、另外C++class中一些特有修饰关键字,python也是没有的

如C++中常见的

friend(友源)

static(静态)

virtual(虚继承)

const (只读)

Auto,此外访问控制符public/private/protected),函数重载,析构函数也都是C++中独有的,python中都是没有的。

7.5、python独有,而C++没有特性

Python 的这些特性是 "动态、灵活" 的体现,C++(静态编译型)无法原生支持:

  1. 动态添加 / 删除类 / 实例属性 Python 运行时可给类 / 实例新增属性(如obj.new_attr = 10)、删除属性(del obj.attr);C++ 类的属性是编译期固定的,无法动态修改。

  2. 动态修改实例类型 Python 可通过obj.__class__ = 新类修改实例的类型;C++ 实例的类型是编译期确定的,无法动态变更。

  3. __init__外的动态初始化 Python 可在任意方法 / 外部代码中给实例绑定属性(无需在__init__中声明);C++ 实例属性必须在类中声明,且只能在构造函数中初始化。

  4. 元类(Metaclass) Python 的元类是 "类的类",可自定义类的创建逻辑(如type动态创建类);C++ 无元类概念,类的结构由编译器静态解析。

  5. 属性装饰器(@property Python 用@property可将方法伪装成属性(实现 getter/setter 的简洁语法);C++ 需手动写get_xxx()/set_xxx()方法,无原生装饰器语法。

相关推荐
叫我辉哥e12 小时前
新手进阶Python:办公看板集成多数据源+ECharts高级可视化
开发语言·python·echarts
猛扇赵四那边好嘴.2 小时前
Flutter 框架跨平台鸿蒙开发 - 问答社区应用开发教程
开发语言·javascript·flutter·华为·harmonyos
C_心欲无痕2 小时前
Next.js 路由系统对比:Pages Router vs App Router
开发语言·前端·javascript
LawrenceLan2 小时前
Flutter 零基础入门(二十二):Text 文本组件与样式系统
开发语言·前端·flutter·dart
程序员敲代码吗2 小时前
如何从Python初学者进阶为专家?
jvm·数据库·python
kylezhao20192 小时前
C# 各种类型转换深入剖析
开发语言·c#
呉師傅2 小时前
东芝3525AC彩色复印机打印配件寿命和打印错误记录方法【实际操作】
运维·服务器·网络·windows·电脑
hxjhnct2 小时前
JavaScript 的 new会发生什么
开发语言·javascript
少控科技2 小时前
QT进阶日记004
开发语言·qt