python基础
- 语法基础
-
- 数据类型
-
- 主要数据类型
- 特别注意
-
- 1.tuple与list的异同
- 2.字符串字面常量表示
- 3.字符串常用方法
- 4.字符串的转义与防转义
- 5.字符串编码与字符数组
- [6.list, dict, set常用方法](#6.list, dict, set常用方法)
- 流程语句
- 表达式
-
- [列表推导式 list](#列表推导式 list)
- [字典推导式 dict](#字典推导式 dict)
- [集合推导式 set](#集合推导式 set)
- 运算符优先级
- 函数
-
- 函数定义
- 函数进阶
-
- 嵌套函数
- [闭包 Closure](#闭包 Closure)
- 作用域与生命周期
- [生成器 Generators](#生成器 Generators)
- 内置函数
-
- [enumerate - 枚举迭代](#enumerate - 枚举迭代)
- [eval - 执行字符串表达式](#eval - 执行字符串表达式)
- [hasattr / getattr / setattr - 管理属性](#hasattr / getattr / setattr - 管理属性)
- [zip - 并行迭代多个序列](#zip - 并行迭代多个序列)
- [sorted - 排序](#sorted - 排序)
- [isinstance / issubclass - 类型检查](#isinstance / issubclass - 类型检查)
- lambda表达式
- functools.partial
- 函数装饰器
- 面向对象编程
语法基础
数据类型
主要数据类型
1. 数字类型
python
int_num = 42 # 整型 (Python 3中int无大小限制)
float_num = 3.14 # 浮点型
complex_num = 2+3j # 复数型
bool_val = True # 布尔型 (True/False)
2. 序列类型
python
str_val = "hello" # 字符串
list_val = [1, 2, 3] # 列表
tuple_val = (1, 2, 3) # 元组
3. 集合类型
python
set_val = {1, 2, 3} # 集合 (无序、不重复)
frozenset_val = frozenset([1, 2, 3]) # 不可变集合
4. 映射类型
python
dict_val = {"name": "John", "age": 25} # 字典 (类似 C++的 map)
5. 其他
python
bytes_val = b"hello" # 字节串 (处理二进制数据)
bytearray_val = bytearray(b"hello") # 可变的字节数组
None_val = None # 空值 (类似 C++的 nullptr)
特别注意
1.tuple与list的异同
相同点:都是有序容器,都可以索引访问,都可以迭代
不同点:list可以修改添加删除元素,tuple不可以
(tuple 作为不可变数据的集合,使用场景如坐标、配置项)
2.字符串字面常量表示
python
s1 = 'hello' # 单引号
s2 = "world" # 双引号
s3 = """这是
多行
字符串"""
s4 = '''这也是
多行字符串''' # 三引号 (多行字符串)
# 原始字符串 (raw string,不转义)
path = r"C:\Users\name\file.txt" # 反斜杠不被转义
# 格式化字符串 (f-string, Python 3.6+)
name = "John"
age = 25
s5 = f"姓名: {name}, 年龄: {age}" # 直接嵌入变量
3.字符串常用方法
python
s = "Hello, Python!"
# 基本操作
print(len(s)) # 长度 (14)
print(s[0]) # 索引 (H)
print(s[7:13]) # 切片 (Python)
print("Py" in s) # 成员检查 (True)
# 大小写转换
print(s.lower()) # 全小写 (hello, python!)
print(s.upper()) # 全大写 (HELLO, PYTHON!)
print(s.title()) # 首字母大写,其余小写 (Hello, Python!)
# 查找和替换
print(s.find("Python")) # 返回目标索引 (7)
print(s.replace("Python", "World")) # 替换 (Hello, World!)
print(s.count("o")) # 统计出现次数 (2)
# 分割和连接
print(s.split(",")) # 拆分字符串 (['Hello', ' Python!'])
print("-".join(["a", "b", "c"])) # 连接字符串 (a-b-c)
# 去除空白
print(" hello ".strip()) # 首尾去除 (hello)
print(" hello ".lstrip()) # 左去除 (hello )
print(" hello ".rstrip()) # 右去除 ( hello)
# 格式化
print("{} is {}".format("Python", "great")) # Python is great
print("{1} before {0}".format("A", "B")) # B before A
# 检查类型
print(s.startswith("Hello")) # True
print(s.endswith("!")) # True
print(s.isalpha()) # 是否只有字母 (False)
print("123".isdigit()) # True
4.字符串的转义与防转义
python
# 转义字符 (类似 C++)
print("Line 1\nLine 2") # 换行 (\n)
print("Tab\there") # 制表符 (\t)(Tab here)
print("She said: \"Hello\"") # 双引号 (\" \")(She said: "Hello")
print('It\'s mine') # 单引号 (\')(It's mine)
print("Backslash: \\") # 反斜杠 (\\)(Backslash: \)
# 原始字符串 (防转义) - Python特有
# 常用于正则表达式、Windows路径
print(r"C:\Users\name") # C:\Users\name
print(r"New\nLine") # New\nLine (不转义)
# 与C++对比:
"""
C++中的原始字符串字面量:
string path = R"(C:\Users\name)";
Python中更简洁:
path = r"C:\Users\name"
C++中多行原始字符串:
string sql = R"(
SELECT * FROM users
WHERE id = 1
)";
Python中:
sql = """
SELECT * FROM users
WHERE id = 1
"""
"""
5.字符串编码与字符数组
python
s = "你好世界" # Unicode字符串
# 编码转换
# string → bytes (编码)
utf8_bytes = s.encode("utf-8")
gbk_bytes = s.encode("gbk")
# bytes → string (解码)
s2 = utf8_bytes.decode("utf-8") # 恢复为字符串
python
s = "Hello"
# 遍历字符
for ch in s:
print(ch) # H e l l o
# 获取字符的Unicode码点
print(ord("A")) # 65
print(chr(65)) # 'A'
# 字符串不可变,但可以转换为list修改
lst = list("Hello")
lst[0] = "J"
new_str = "".join(lst) # "Jello"
s[0] = 'J' # 不允许! 字符串是不可变的Unicode对象
6.list, dict, set常用方法
python
# 列表常用方法
lst = [1, 2, 3]
lst.append(4) # 添加
lst.extend([5, 6]) # 扩展
lst.insert(1, 1.5) # 插入
lst.remove(2) # 删除元素
lst.pop() # 弹出最后一个
lst.sort() # 排序
lst.reverse() # 反转
lst.index(3) # 查找索引
lst.count(1) # 计数
# 字典常用方法
d = {"a": 1, "b": 2}
d["c"] = 3 # 添加/修改
d.get("a") # 安全获取
d.keys() # 所有键
d.values() # 所有值
d.items() # 键值对
d.pop("a") # 弹出
d.update({"d": 4}) # 更新
# 集合常用方法
s = {1, 2, 3}
s.add(4) # 添加
s.remove(2) # 删除
s.union({3, 4, 5}) # 并集
s.intersection({2,3})# 交集
s.difference({2,3}) # 差集
流程语句
赋值语句
python
# 基本赋值 (不需要声明类型)
x = 10 # 整数
name = "John" # 字符串
pi = 3.14159 # 浮点数
# 多重赋值
a = b = c = 0 # 所有变量赋相同值
x, y, z = 1, 2, 3 # 同时赋不同的值
# 解包赋值
x, y = (10, 20) # 元组解包
person = {"name": "John", "age": 30}
name, age = person.values() # 字典解包
first, *middle, last = [1, 2, 3, 4, 5] # 列表解包
条件语句
python
# 基本if语句
age = 18
if age >= 18:
print("成年")
else:
print("未成年")
# if/elif/else嵌套
score = 85
if score >= 90:
grade = "A"
print("优秀")
elif score >= 80:
grade = "B"
print("良好")
else:
grade = "F"
print("不及格")
# 三元运算符
age = 20
status = "成年" if age >= 18 else "未成年"
print(status)
# 链式比较
x = 15
if 10 <= x <= 20:
print("x在10到20之间")
# 条件中的布尔运算:and, or, not 运算符
循环语句
python
fruits = ["apple", "banana", "cherry"]
# for循环
for fruit in fruits: # 直接遍历元素
print(fruit)
# for循环获取索引
for i, fruit in enumerate(fruits, start=1):
print(f"第{i}个水果: {fruit}")
# range函数范围迭代
for i in range(0, 10, 2): # 0,2,4,6,8
print(i)
# while循环
while count < 5:
print(f"Count: {count}")
count += 1
# for/else语句: for循环正常结束(没有break)时执行else
for num in numbers:
if num == target:
print(f"找到了 {target}")
break
else:
print(f"没有找到 {target}")
# while/else语句: while循环正常结束(条件为假)时执行else
while count < max_count:
if count == 3:
print("提前退出")
break
print(f"Count: {count}")
count += 1
else: # 循环正常结束(条件变为False)时执行
print("循环正常结束")
# zip函数并行迭代
names = ["Alice", "Bob", "Charlie"]
ages = [25, 30, 35]
for name, age in zip(names, ages):
print(f"{name} is {age} years old")
表达式
列表推导式 list
python
squares = [x**2 for x in range(10) if x % 2 == 0] # [0, 4, 16, 36, 64]
# 可以带多个条件
pairs = [(x, y) for x in range(3) for y in range(2)]
# 带多重循环
字典推导式 dict
python
numbers = [1, 2, 3, 4, 5, 6]
even_squares = {x: x**2 for x in numbers if x % 2 == 0}
print(even_squares) # {2: 4, 4: 16, 6: 36}
集合推导式 set
python
even_squares = {x**2 for x in range(10) if x % 2 == 0} # {0, 4, 16, 36, 64}
运算符优先级
从高到低的优先级:
- ** 指数(幂运算)
- +x, -x, ~x 正号、负号、按位取反
- *, /, //, % 乘、除、整除、取模
- +, - 加、减
- <<, >> 左移、右移位运算
- & 按位与
- ^ 按位异或
- | 按位或
- <, <=, >, >=, !=, ==, is, is not, in, not in 比较运算符、身份运算符、成员运算符
- not 逻辑非
- and 逻辑与
- or 逻辑或
- if - else 条件表达式
- =, +=, -=, *= 等 赋值运算符
Python的 is, is not 比较对象标识(内存地址)
函数
函数定义
python
# Python函数定义:def 函数名(参数):
def greet(name):
return f"Hello, {name}!"
# 调用函数
result = greet("Alice")
print(result) # Hello, Alice!
返回值
可以使用return显式返回,或不使用return默认返回None类型
可以返回多个值(实际上是返回一个元组)
python
# 返回
return min(numbers), max(numbers)
# 调用
minimum, maximum = min_max([1, 5, 3, 9, 2])
函数参数
1.使用位置参数
python
def describe_person(name, age, city):
return f"{name} is {age} years old and lives in {city}"
print(describe_person("Bob", 25, "Beijing"))
# 使用关键字可打乱顺序
print(describe_person(age=25, city="Beijing", name="Bob"))
2.默认参数时默认值只在定义时计算一次,并绑定到函数对象
python
def append_to_list(value, my_list=None):
3.使用可变位置参数(*args)
python
def sum_numbers(*args): # *args收集所有位置参数为元组
return sum(args)
print(sum_numbers(1, 2, 3)) # 6
print(sum_numbers(1, 2, 3, 4, 5)) # 15
print(sum_numbers()) # 0
4.使用可变关键字参数(**kwargs)
python
def print_info(**kwargs): # **kwargs收集所有位置参数为字典
for key, value in kwargs.items():
print(f"{key}: {value}")
print_info(name="Alice", age=25, city="Beijing")
5.正确的参数顺序:位置参数、*args、默认参数、**kwargs
6.参数传递机制 :Python是"对象引用传递"
不可变对象(数字、字符串、元组)不会被修改,可变对象(列表、字典、集合)可以被修改
python
def modify_list(lst):
lst.append(4) # 修改原列表
lst = [10, 20, 30] # 重新赋值会创建新列表
函数进阶
嵌套函数
允许在函数内部定义函数
python
def outer_function():
def inner_function():
print("内部函数执行")
inner_function() # 只能在outer_function内部调用
print("外部函数结束")
outer_function()
闭包 Closure
闭包由两部分组成:一个函数,该函数创建时的环境(即其外部作用域的变量引用)
可以实现:状态保持,信息隐藏,代码复用,灵活的函数组合
python
def make_multiplier(factor): # 创建乘法器函数,因子为 factor
def multiplier(x): # 实际的乘法函数
return x * factor
return multiplier # 返回内部函数
# 使用
times_two = make_multiplier(2) # times_two现在是 multiplier函数
times_three = make_multiplier(3)
print(times_two(5)) # 10
print(times_three(5)) # 15
作用域与生命周期
1.LEGB作用域规则
Python作用域层次(从内到外):
L - Local:局部作用域(函数内部)
E - Enclosing:嵌套函数的外层函数作用域
G - Global:模块/全局作用域
B - Built-in:内置作用域
python
x = "global" # G: 全局作用域
def outer():
x = "enclosing" # E: 闭包作用域
def inner():
x = "local" # L: 局部作用域
# 访问内置作用域
print(f"内置函数: {len([1,2,3])}") # B: 内置作用域
inner()
outer()
2.当需要修改外层作用域的变量时进行声明(读取变量不需要声明)
python
global count # 外层和局部作用域内声明使用全局变量
nonlocal x # 局部作用域内声明使用外层函数的变量
3.查询命名空间内变量
locals() 返回局部命名空间,globals() 返回全局命名空间
python
global_var = 10
def test():
local_var = 100
print("局部变量:", locals()) # {'local_var': 100}
print("全局变量:", globals().keys()) # dict_keys(['global_var', 'test'])
test()
4.变量的生命周期
全局变量:整个程序运行期间
局部变量:函数调用期间
闭包变量:与外层函数相同
生成器 Generators
优势:惰性计算,状态保持,流式处理
1.基本用法
python
# 生成器函数
def simple_generator():
print("开始执行")
yield 1
print("继续执行")
yield 2
print("结束执行")
yield 3
# 创建生成器对象
gen = simple_generator()
print(type(gen)) # <class 'generator'>
# 使用next()获取值
print(next(gen)) # 开始执行 \n 1
print(next(gen)) # 继续执行 \n 2
print(next(gen)) # 结束执行 \n 3
# 超出3后StopIteration异常
# 使用for循环(自动处理StopIteration)
gen = simple_generator()
for value in gen:
print(f"循环中: {value}")
2.管道式处理
python
def source(data):
"""数据源"""
for item in data:
yield item
def filter_even(stream):
"""过滤偶数"""
for item in stream:
if item % 2 == 0:
yield item
def square(stream):
"""平方"""
for item in stream:
yield item ** 2
# 构建处理管道
data = range(10)
result = square(filter_even(source(data)))
print(f"\n管道结果: {list(result)}") # [0, 4, 16, 36, 64]
3.yield from语法
python
yield from it
# 等价于
for item in it:
yield item
4.双向通道
python
def running_average():
"""计算运行平均值(支持发送新值)"""
total = 0
count = 0
average = 0
while True:
# 接收发送的值
value = yield average
if value is None:
break
total += value
count += 1
average = total / count
# 创建生成器
avg_gen = running_average()
# 启动生成器,在 yield 处暂停执行,返回 average 的当前值 0
next(avg_gen)
# 发送数据并获取当前平均值
# 从上次暂停的 yield 处恢复执行,value被赋值为 10,直到 yield 处再次暂停,返回当前 average值
print(avg_gen.send(10)) # 10.0
print(avg_gen.send(20)) # 15.0
print(avg_gen.send(30)) # 20.0
# 关闭生成器
avg_gen.close()
内置函数
enumerate - 枚举迭代
主要来获取索引,设置起始值
python
for index, fruit in enumerate(fruits, start=1):
print(f"第{index}个水果: {fruit}")
eval - 执行字符串表达式
实际使用时考虑安全问题
python
result = eval("2 + 3 * 5") # 基本数学运算
result = eval("x + y * 2") # 使用变量
result = eval("math.sqrt(16)") # 使用函数
hasattr / getattr / setattr - 管理属性
hasattr(obj, name) - 检查属性是否存在
getattr(obj, name[, default]) - 获取属性值
setattr(obj, name, value) - 设置属性值
python
print(hasattr(person, "name")) # 对象名,属性名/方法名 (True)
print(getattr(person, "name", "未设置")) # 对象名,属性名,默认值 (Alice)
setattr(person, "city", "Beijing") # 对象名,属性名,修改值
zip - 并行迭代多个序列
不等长序列以最短的为准
python
for name, age, city in zip(names, ages, cities):
print(f"{name} ({age}岁) 来自 {city}")
sorted - 排序
python
numbers = [3, 1, 4, 1, 5, 9, 2, 6]
print(sorted(numbers)) # [1, 1, 2, 3, 4, 5, 6, 9]
print(sorted(numbers, reverse=True)) # [9, 6, 5, 4, 3, 2, 1, 1]
isinstance / issubclass - 类型检查
python
print(isinstance(42, int)) # True
print(isinstance("hello", (str, int))) # True (是str或int)
class Animal: pass
class Dog(Animal): pass
class Cat(Animal): pass
print(issubclass(Dog, Animal)) # True
print(issubclass(Dog, Cat)) # False
lambda表达式
lambda语法:lambda 参数列表: 表达式
python
add = lambda x, y: x + y
# 等价
def add(x, y):
return x + y
print(add(3, 5)) # 8
常用场景
python
# 1.按键值排序
students.sort(key=lambda s: s["grade"])
print("按成绩排序:", [s["name"] for s in students])
# 2.映射和过滤
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
squares = list(map(lambda x: x**2, numbers)) # 平方: [1, 4, 9, 16, 25, 36, 49, 64, 81]
evens = list(filter(lambda x: x % 2 == 0, numbers)) # 偶数: [2, 4, 6, 8]
lambda的限制:
1.只能包含单个表达式,不能包含语句
2.不能有return语句(隐式返回表达式结果)
3.不能包含循环、条件语句(但可以使用条件表达式)
4.不能定义变量(但可以使用默认参数技巧)
functools.partial
基本语法:partial(func, *args, **kwargs)
作用:固定函数的部分参数,创建新函数
python
from functools import partial
def power(base, exponent):
return base ** exponent
# 固定exponent参数
square = partial(power, exponent=2)
print(square(3)) # 9 (3**2)
print(square(5)) # 25 (5**2)
# 固定base参数
power_of_two = partial(power, 2)
print(power_of_two(3)) # 8 (2**3)
print(power_of_two(4)) # 16 (2**4)
函数装饰器
1.简单装饰器
python
def simple_decorator(func):
"""简单装饰器,包装原函数"""
def wrapper():
print("函数执行前")
result = func()
print("函数执行后")
return result
return wrapper
@simple_decorator
def say_hello():
print("Hello, World!")
say_hello()
# 函数执行前
# Hello, World!
# 函数执行后
2.多个装饰器
python
@decorator1
@decorator2
def say_hello():
print("Hello!")
say_hello()
# 装饰器1 前
# 装饰器2 前
# Hello!
# 装饰器2 后
# 装饰器1 后
3.类作为装饰器,可以保持状态跨多次调用
python
class CountCalls:
"""统计函数调用次数的装饰器"""
def __init__(self, func):
self.func = func
self.call_count = 0
def __call__(self, *args, **kwargs):
self.call_count += 1
print(f"{self.func.__name__} 已被调用 {self.call_count} 次")
return self.func(*args, **kwargs)
@CountCalls # @CountCalls等价于say_hello = CountCalls(say_hello)
def say_hello(name):
return f"Hello, {name}!"
print(say_hello("Alice")) # say_hello 已被调用 1 次; Hello, Alice!
print(say_hello("Bob")) # say_hello 已被调用 2 次; Hello, Bob!
print(f"总调用次数: {say_hello.call_count}") # 总调用次数: 2
面向对象编程
类
基本定义
python
class Person:
# 类变量:所有实例共享
species = "Homo sapiens"
count = 0
# 构造方法:初始化实例
def __init__(self, name, age):
# 实例变量:每个实例独立,可动态添加
self.name = name
self.age = age
Person.count += 1 # 修改类变量
self.id = Person.count # 实例 ID
# 实例方法:访问类和实例变量,需要显式 self 参数
def greet(self):
return f"你好,我是{self.name},今年{self.age}岁"
# 类方法:访问类变量,需要显式 cls 参数
@classmethod
def get_count(cls):
return f"已创建{cls.count}个人类实例"
# 静态方法:不访问实例或类变量,实例和类都可使用
@staticmethod
def is_adult(age):
return age >= 18
# 创建实例
alice = Person("Alice", 25)
bob = Person("Bob", 17)
# 使用方法
print(alice.greet()) # 你好,我是Alice,今年25岁
print(Person.get_count()) # 已创建2个人类实例
print(Person.is_adult(20)) # True
# 访问属性
print(f"物种: {Person.species}")
print(f"Alice的物种: {alice.species}")
print(f"Bob的ID: {bob.id}")
特殊方法
Python 解释器会在特定时机自动调用它们
基本特殊方法
初始化方法:创建实例时调用
python
def __init__(self, x=0, y=0):
字符串表示:str(obj) 和 print(obj) 时调用,如果不定义会使用__repr__
python
def __str__(self):
正式字符串表示:repr(obj) 时调用,方便调试需要
python
def __repr__(self):
比较运算符重载
等于:self == other
python
def __eq__(self, other):
不等于:self != other
python
def __ne__(self, other):
哈希值:使对象 self 可作为字典键
python
def __hash__(self):
return hash((self.x, self.y))
继承
基本继承
python
class Animal:
"""动物基类"""
def __init__(self, name, age):
self.name = name
self.age = age
def speak(self): # 动物叫
raise NotImplementedError("子类必须实现此方法")
def info(self): # 动物信息
return f"{self.name},{self.age}岁"
class Dog(Animal):
"""狗类"""
def __init__(self, name, age, breed):
# 调用父类构造方法
super().__init__(name, age)
self.breed = breed
def speak(self):
return "汪汪!"
def info(self):
base_info = super().info()
return f"{base_info},品种: {self.breed}"
class Cat(Animal):
"""猫类"""
def __init__(self, name, age, color):
super().__init__(name, age)
self.color = color
def speak(self):
return "喵喵!"
def info(self):
base_info = super().info()
return f"{base_info},颜色: {self.color}"
# 使用
animals = [
Dog("旺财", 3, "金毛"),
Cat("咪咪", 2, "橘色"),
Dog("小黑", 4, "拉布拉多")
]
for animal in animals:
print(f"{animal.info()} -> {animal.speak()}")
多重继承
允许多重继承,可能出现 MRO 冲突
python
class C(A, B):
pass
方法解析顺序:C -> A -> B -> base
多重继承时 super() 按这个顺序调用前一个类的方法
(C3 线性化算法:子类优先于父类,继承顺序从左到右)
属性 property
property本质:将方法调用伪装成属性访问
1.使用@property装饰器
python
@property
def name(self): # 相当于 get
return self._name
@name.setter
def name(self, value): # 相当于 set
if not value:
raise ValueError("姓名不能为空")
self._name = value
@name.deleter
def name(self):
del self._name
# 使用
p = Person("Alice", 25)
print(p.name) # 获取name \n Alice
p.name = "Bob" # 设置name: Bob
del p.name # 删除name
2.使用property()函数
python
name = property(
fget=get_name,
fset=set_name,
fdel=del_name,
doc="姓名属性"
)
命名空间
成员
类命名空间:类变量、类方法、静态方法、属性
实例命名空间:实例变量
成员都储存在字典 dict 中
访问控制
所有成员都是"公开"的,通过命名约定来实现访问控制
类变量与实例变量规则相同
公开 (Public) 可以直接访问
受保护 (Protected) 约定为"内部使用",不强制限制,单下划线前缀
私有 (Private) 会进行名称改写,外部不可访问,双下划线前缀
动态性
Python可以在运行时修改类结构
使用场景:动态配置数据库对象
python
# 初始类与实例
class DynamicClass:
def __init__(self, name):
self.name = name
# 创建实例
obj = DynamicClass("初始对象")
动态属性
1.使用等号赋值
python
obj.value = 42 # 实例属性
del obj.value
DynamicClass.class_var = 26 # 类属性
2.使用__dict__操作命名空间
python
obj.__dict__['new_attr'] = 47
obj.__dict__['name'] = "修改后对象"
new_attrs = {'x': 10, 'y': 20, 'z': 30} # 批量添加属性
obj.__dict__.update(new_attrs)
3.使用 setattr() 方法
python
setattr(obj, '属性名', "属性值")
动态类方法
python
def new_method(self):
return f"坐标: ({self.x}, {self.y}, {self.z})"
DynamicClass.get_coords = new_method
print(f"调用新方法: {obj.get_coords()}")
动态类
可以动态创建新类和修改继承
函数与方法
差异
函数 (Function) ≠ 方法 (Method)
函数 = 静态方法
方法 = 静态方法 + 类方法 + 实例方法
方法绑定
绑定方法 (Bound Method) = 实例方法绑定到特定实例 或 类方法绑定到类
未绑定方法 (Unbound Method) = 普通函数(比如实例方法还未绑定)
垃圾回收器 GC
1.引用计数 (主要机制)
每个对象维护引用计数
计数为 0 时立即回收
2.分代回收 (提高效率)
三代:0(年轻)、1(中年)、2(老年)
新对象在第0代,经历过一次垃圾回收仍存活的对象在第1代
存活时间越长,移到更高代
每代有回收阈值
3.标记-清除 (mark-sweep)
从根对象(全局变量、栈变量等)开始标记
标记所有可达对象
清除未标记对象(不可达)
4.弱引用 (weakref)
不增加引用计数的引用
用于打破循环引用
Python vs C++
关键差异:
-
内存布局:
Python: 对象是堆上的字典(dict),通过引用访问
C++: 对象是连续内存块,栈或堆上分配
-
属性访问:
Python: 动态查找(dict + MRO)
C++: 静态偏移计算(编译时确定)
-
继承实现:
Python: 通过MRO列表查找
C++: 通过虚函数表(vtable)和偏移
-
多态性:
Python: 鸭子类型,运行时确定
C++: 虚函数,编译时确定接口
-
内存管理:
Python: 引用计数 + 垃圾回收
C++: 手动管理或智能指针