Python高级特性:对象比较、拷贝机制与作用域
1. == 与 is 的区别
1.1 基本概念
==
:比较对象的值是否相等is
:比较对象的身份(内存地址)是否相同
1.2 详细示例
# 值比较
a = [1, 2, 3]
b = [1, 2, 3]
print(a == b) # True(值相等)
print(a is b) # False(不同对象)
# 小整数对象池
x = 256
y = 256
print(x is y) # True(在对象池范围内)
m = 257
n = 257
print(m is n) # False(超出对象池范围)
1.3 Python对象池机制
- 小整数对象池:范围为[-5, 257)
- 字符串驻留机制:相同的字符串常量共用同一个对象
# 字符串驻留示例
s1 = "hello"
s2 = "hello"
print(s1 is s2) # True
# 长字符串或包含空格的字符串可能不会驻留
s3 = "hello world"
s4 = "hello world"
print(s3 is s4) # 结果可能是False
2. 拷贝机制
2.1 赋值操作
# 简单赋值是引用传递
list1 = [1, 2, [3, 4]]
list2 = list1
list2[0] = 100
print(list1) # [100, 2, [3, 4]]
print(list2) # [100, 2, [3, 4]]
2.2 浅拷贝(Shallow Copy)
浅拷贝创建新对象,但内部对象引用不变。
import copy
# 浅拷贝的三种方式
# 1. 使用copy模块
list1 = [1, 2, [3, 4]]
list2 = copy.copy(list1)
# 2. 使用切片
list3 = list1[:]
# 3. 使用工厂函数
list4 = list(list1)
# 修改测试
list2[0] = 100
list2[2][0] = 300
print(list1) # [1, 2, [300, 4]]
print(list2) # [100, 2, [300, 4]]
2.3 深拷贝(Deep Copy)
深拷贝创建新对象,并递归地复制所有内部对象。
import copy
# 深拷贝示例
original = [1, [2, 3], {'a': 4}]
deep_copied = copy.deepcopy(original)
# 修改测试
deep_copied[1][0] = 200
deep_copied[2]['a'] = 400
print(original) # [1, [2, 3], {'a': 4}]
print(deep_copied) # [1, [200, 3], {'a': 400}]
2.4 特殊情况
2.4.1 不可变类型
# 元组的特殊情况
t1 = (1, 2, [3, 4])
t2 = copy.deepcopy(t1)
# 可以修改元组中的可变对象
t2[2][0] = 300
print(t1) # (1, 2, [3, 4])
print(t2) # (1, 2, [300, 4])
2.4.2 字典的拷贝
# 字典的内置copy方法(浅拷贝)
dict1 = {'a': [1, 2], 'b': 3}
dict2 = dict1.copy()
dict2['a'][0] = 100
print(dict1) # {'a': [100, 2], 'b': 3}
print(dict2) # {'a': [100, 2], 'b': 3}
3. 进制与位运算
3.1 进制转换
# 十进制转其他进制
num = 42
print(bin(num)) # 0b101010 (二进制)
print(oct(num)) # 0o52 (八进制)
print(hex(num)) # 0x2a (十六进制)
# 其他进制转十进制
print(int('101010', 2)) # 42
print(int('52', 8)) # 42
print(int('2a', 16)) # 42
3.2 位运算操作
x = 60 # 0011 1100
y = 13 # 0000 1101
# 按位与
print(x & y) # 12 (0000 1100)
# 按位或
print(x | y) # 61 (0011 1101)
# 按位异或
print(x ^ y) # 49 (0011 0001)
# 按位取反
print(~x) # -61
# 左移右移
print(x << 2) # 240 (1111 0000)
print(x >> 2) # 15 (0000 1111)
4. 作用域与命名空间
4.1 命名空间类型
- 局部命名空间(Local)
- 嵌套函数命名空间(Enclosing)
- 全局命名空间(Global)
- 内置命名空间(Built-in)
4.2 作用域查找顺序(LEGB规则)
# LEGB示例
x = 'global'
def outer():
x = 'enclosing'
def inner():
x = 'local'
print(x) # 输出 'local'
inner()
print(x) # 输出 'enclosing'
outer()
print(x) # 输出 'global'
4.3 globals()和locals()
# globals()示例
global_var = 100
def test_function():
local_var = 200
print(globals()) # 显示全局变量字典
print(locals()) # 显示局部变量字典
test_function()
4.4 变量访问限制
# 私有化示例
class MyClass:
def __init__(self):
self.public = "公有变量"
self._protected = "保护变量"
self.__private = "私有变量"
def get_private(self):
return self.__private
obj = MyClass()
print(obj.public) # 正常访问
print(obj._protected) # 可以访问,但不推荐
# print(obj.__private) # 报错
print(obj.get_private()) # 通过方法访问私有变量
4.5 property属性
class Person:
def __init__(self):
self.__age = 0
@property
def age(self):
return self.__age
@age.setter
def age(self, value):
if 0 <= value <= 150:
self.__age = value
else:
raise ValueError("Age must be between 0 and 150")
person = Person()
person.age = 25 # 使用setter
print(person.age) # 使用getter