python自学笔记第三节---类型转换 + 深浅拷贝 + 可变与不可变对象


---

## 一、类型转换

```python
f1 = 1.2
print(f1, type(f1)) # 1.2 <class 'float'>

f2 = 1.2
print(int(f2), type(f2)) # 1 <class 'float'>

# 强转:float 转 int
f2 = int(f2)
print(f2, type(f2)) # 1 <class 'int'>
print(int(1.8)) # 1(直接截断,非四舍五入)

# str 转 int
f2 = str(f2)
print(f2, type(f2)) # 1 <class 'str'>

# int 转 float
print(float(11)) # 11.0 后面加一位小数 0

# 任何类型都能转为 str
arr = [1, 2, 3, 4, 5]
st = str(arr)
print(st, type(st)) # [1, 2, 3, 4, 5] <class 'str'>

f1 = 1.82020
print(str(f1)) # 1.8202 去掉结尾的 0
```

- Python 的强转函数直接以类型名为函数名:`int() / float() / str() / list() / dict()`,比 Java 的 `Integer.parseInt` 简洁。
- `int(1.8)` 是直接截断而非四舍五入,这点要注意。

## 二、eval 函数:执行表达式

```python
# eval 执行表达式,返回字符串表达式的值
print(eval(str("10 + 10"))) # 20

# eval 可以实现 list / dict / tuple / str 之间的转换
# str 转 list
st1 = "[1,2,3,[4,5,6]]"
arr = eval(st1)
print(arr, type(arr)) # [1, 2, 3, [4, 5, 6]] <class 'list'>

# str 转 dict
st1 = '{"name":"wxy","age":18}'
dic = eval(st1)
print(dic, type(dic)) # {'name': 'wxy', 'age': 18} <class 'dict'>
```

- `eval` 能把字符串当成 Python 表达式执行,相当于 Java 没有的"动态求值"能力。
- ⚠️ **安全警告**:`eval` 执行任意字符串有注入风险,生产环境慎用,特别是处理用户输入时。

## 三、list() 函数转换

```python
# list() 将可迭代对象转为列表
# 支持 str / tuple / dict / set

# str 转 list
arr = list("abcdefg")
print(arr, type(arr)) # ['a', 'b', 'c', 'd', 'e', 'f', 'g'] <class 'list'>

# tuple 转 list
print(list((1, 2, 3, 4, 5))) # [1, 2, 3, 4, 5]

# dict 转 list(只取键值成数组)
print(list({"name": "wxy", "age": 18})) # ['name', 'age']

# set 转 list
print(list({1, 2, 3, 4, 5})) # [1, 2, 3, 4, 5]
```

- `dict` 转 `list` 只取键,这点和 Java 的 `map.keySet().toArray()` 类似。

## 四、赋值 vs 深浅拷贝

### 4.1 赋值:一个值的改变会影响另一个值

```python
arr = [1, 2, 3, [4, 5, 6]]
arr2 = arr
arr.append("999")
print(arr) # [1, 2, 3, [4, 5, 6], '999']
print(arr2) # [1, 2, 3, [4, 5, 6], '999']

arr = [1, 2, 3, [4, 5, 6]]
arr2 = arr
arr2.append("999")
print(arr) # [1, 2, 3, [4, 5, 6], '999']
print(arr2) # [1, 2, 3, [4, 5, 6], '999']
```

- 赋值只是把引用指向同一块内存,相当于 Java 的 `=` 引用传递。

### 4.2 浅拷贝:数据半共享

```python
import copy

arr = [1, 2, 3, [4, 5, 6]]
arr2 = copy.copy(arr)
arr2.append("999")
print(arr) # [1, 2, 3, [4, 5, 6]]
print(arr2) # [1, 2, 3, [4, 5, 6], '999']

# id() 看内存地址
print(id(arr), id(arr2)) # 外层内存地址不同
print(id(arr[3]), id(arr2[3])) # 内层地址相同!
```

- 浅拷贝:外层是新对象,内层仍共享引用。
- 优点:拷贝速度快、占用空间小、效率高。
- 对应 Java 的 `new ArrayList<>(oldList)`,浅拷贝行为一致。

### 4.3 深拷贝:数据完全不共享

```python
arr = [1, 2, 3, [4, 5, 6]]
arr2 = copy.deepcopy(arr)
arr2.append("999")
print(arr) # [1, 2, 3, [4, 5, 6]]
print(arr2) # [1, 2, 3, [4, 5, 6], '999']

print(id(arr), id(arr2)) # 外层地址不同
print(id(arr[3]), id(arr2[3])) # 内层地址也不同!
```

- 深拷贝:所有层级都重新创建,互不影响。
- 对应 Java 的序列化/反序列化或递归 clone。

## 五、可变对象与不可变对象

### 5.1 可变对象:list / dict / set

```python
# 含义:变量对应的值可以修改,内存地址不变
arr = [1, 2, 3, [4, 5, 6]]
print(arr) # [1, 2, 3, [4, 5, 6]]
print(id(arr))
arr.append("999")
print(arr) # [1, 2, 3, [4, 5, 6], '999']
print(id(arr)) # 内存地址不变!

dic = {"name": "wxy", "age": 18}
print(dic, id(dic))
dic.update({"tel": 123456})
print(dic, id(dic)) # 内存地址不变

se = {1, 2, 3, 4, 5}
print(se, id(se))
se.update({6})
print(se, id(se)) # 内存地址不变
```

### 5.2 不可变对象:基本数据类型、tuple

```python
# 含义:变量对应的值不可修改,修改会变成新值,分配新内存空间
i1 = 10
print(i1, id(i1))
i1 = 11
print(i1, id(i1)) # 内存地址改变!

tup = (1, 2, 3, [4, 5, 6])
print(tup, id(tup))
tup = (1, 2, 3, [4, 5, 6])
print(tup, id(tup)) # 重新赋值,内存地址不同
```

---

## 📌 深浅拷贝与可变性对比表

| 操作 | 外层地址 | 内层地址 | 修改互相影响 |
|------|---------|---------|------------|
| 赋值 `=` | 相同 | 相同 | ✅ 影响 |
| 浅拷贝 `copy.copy` | 不同 | 相同 | 内层影响 |
| 深拷贝 `copy.deepcopy` | 不同 | 不同 | ❌ 不影响 |

| 对象类型 | 是否可变 | 修改后内存地址 |
|---------|---------|--------------|
| list / dict / set | 可变 | 不变 |
| int / str / tuple | 不可变 | 改变(新对象) |

---

## 📌 与 Java 的对比

| 概念 | Java | Python |
|------|------|--------|
| 赋值 | 引用传递 | 引用传递 |
| 浅拷贝 | `new ArrayList<>(old)` | `copy.copy()` |
| 深拷贝 | 序列化 / 递归 clone | `copy.deepcopy()` |
| 不可变对象 | `String`、包装类 | `int / str / tuple` |
| 可变对象 | `StringBuilder`、集合 | `list / dict / set` |

> Java 中 `String` 不可变是经典面试题,Python 同理——`int / str / tuple` 都是不可变对象,"修改"本质是创建新对象。理解这点,对后续函数传参、闭包、缓存都至关重要。

---
posted @ 2026-07-25 22:21  爱笑的橘子  阅读(0)  评论(0)    收藏  举报